Cataclysm BN
Character Class Referenceabstract

#include <character.h>

Inheritance diagram for Character:
Creature visitable< Character > player avatar npc standard_npc

Classes

struct  has_mission_item_filter
 

Public Types

enum  water_tolerance { WT_IGNORED = 0 , WT_NEUTRAL , WT_GOOD , NUM_WATER_TOLERANCE }
 
using trap_map = std::map< tripoint, std::string >
 
- Public Types inherited from Creature
enum  Attitude : int { A_HOSTILE , A_NEUTRAL , A_FRIENDLY , A_ANY }
 Simplified attitude towards any creature: hostile - hate, want to kill, etc. More...
 

Public Member Functions

 Character (const Character &)=delete
 
Characteroperator= (const Character &)=delete
 
 ~Character () override
 
Characteras_character () override
 
const Characteras_character () const override
 
character_id getID () const
 
void setID (character_id i, bool force=false)
 
bool is_dead_state () const override
 Returns true if the character should be dead. More...
 
field_type_id bloodType () const override
 
field_type_id gibType () const override
 
bool is_warm () const override
 
bool in_species (const species_id &spec) const override
 
const std::string & symbol () const override
 
virtual int get_str () const
 Getters for stats exclusive to characters. More...
 
virtual int get_dex () const
 
virtual int get_per () const
 
virtual int get_int () const
 
virtual int get_str_base () const
 
virtual int get_dex_base () const
 
virtual int get_per_base () const
 
virtual int get_int_base () const
 
virtual int get_str_bonus () const
 
virtual int get_dex_bonus () const
 
virtual int get_per_bonus () const
 
virtual int get_int_bonus () const
 
int get_speed () const override
 
virtual int ranged_dex_mod () const
 
virtual int ranged_per_mod () const
 
virtual void set_str_bonus (int nstr)
 Setters for stats exclusive to characters. More...
 
virtual void set_dex_bonus (int ndex)
 
virtual void set_per_bonus (int nper)
 
virtual void set_int_bonus (int nint)
 
virtual void mod_str_bonus (int nstr)
 
virtual void mod_dex_bonus (int ndex)
 
virtual void mod_per_bonus (int nper)
 
virtual void mod_int_bonus (int nint)
 
void print_health () const
 
virtual int get_healthy () const
 Getters for health values exclusive to characters. More...
 
virtual int get_healthy_mod () const
 
virtual void mod_healthy (int nhealthy)
 Modifiers for health values exclusive to characters. More...
 
virtual void mod_healthy_mod (int nhealthy_mod, int cap)
 
virtual void set_healthy (int nhealthy)
 Setters for health values exclusive to characters. More...
 
virtual void set_healthy_mod (int nhealthy_mod)
 
int get_stored_kcal () const
 Getter for need values exclusive to characters. More...
 
int max_stored_kcal () const
 
float get_kcal_percent () const
 
int get_thirst () const
 
std::pair< std::string, nc_colorget_thirst_description () const
 
std::pair< std::string, nc_colorget_hunger_description () const
 
std::pair< std::string, nc_colorget_fatigue_description () const
 
int get_fatigue () const
 
int get_sleep_deprivation () const
 
std::pair< std::string, nc_colorget_pain_description () const override
 
virtual void mod_stored_kcal (int nkcal)
 Modifiers for need values exclusive to characters. More...
 
virtual void mod_stored_nutr (int nnutr)
 
virtual void mod_thirst (int nthirst)
 
virtual void mod_fatigue (int nfatigue)
 
virtual void mod_sleep_deprivation (int nsleep_deprivation)
 
virtual void set_stored_kcal (int kcal)
 Setters for need values exclusive to characters. More...
 
virtual void set_thirst (int nthirst)
 
virtual void set_fatigue (int nfatigue)
 
virtual void set_sleep_deprivation (int nsleep_deprivation)
 
void mod_stat (const std::string &stat, float modifier) override
 
m_size get_size () const override
 Get size class of character. More...
 
void recalculate_size ()
 Recalculate size class of character. More...
 
void recalc_speed_bonus ()
 Calculates the various speed bonuses we will get from mutations, etc. More...
 
std::string disp_name (bool possessive=false, bool capitalize_first=false) const override
 Returns either "you" or the player's name. More...
 
std::string skin_name () const override
 Returns the name of the player's outer layer, e.g. More...
 
virtual factionget_faction () const
 
void set_fac_id (const std::string &my_fac_id)
 
float get_dodge_base () const override
 Combat getters. More...
 
float get_hit_base () const override
 
float get_dodge () const override
 
float dodge_roll () override
 
float get_melee () const override
 Returns melee skill level, to be used to throttle dodge practice. More...
 
const tripointpos () const override
 
int sight_range (int light_level) const override
 Returns the player's sight range. More...
 
int unimpaired_range () const
 Returns the player maximum vision range factoring in mutations, diseases, and other effects. More...
 
bool overmap_los (const tripoint_abs_omt &omt, int sight_points)
 Returns true if overmap tile is within player line-of-sight. More...
 
int overmap_sight_range (int light_level) const
 Returns the distance the player can see on the overmap. More...
 
int clairvoyance () const
 Returns the distance the player can see through walls. More...
 
bool sight_impaired () const
 Returns true if the player has some form of impaired sight. More...
 
bool has_alarm_clock () const
 Returns true if the player or their vehicle has an alarm clock. More...
 
bool has_watch () const
 Returns true if the player or their vehicle has a watch. More...
 
void action_taken ()
 Called after every action, invalidates player caches. More...
 
bool is_on_ground () const override
 Returns true if the player is knocked over or has broken legs. More...
 
int swim_speed () const
 Returns the player's speed for swimming across water tiles. More...
 
void add_miss_reason (const std::string &reason, unsigned int weight)
 Adds a reason for why the player would miss a melee attack. More...
 
void clear_miss_reasons ()
 Clears the list of reasons for why the player would miss a melee attack. More...
 
std::string get_miss_reason ()
 Returns an explanation for why the player would miss a melee attack. More...
 
void knock_back_to (const tripoint &to) override
 Knocks the character to a specified tile. More...
 
float fall_damage_mod () const override
 Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels) More...
 
int impact (int force, const tripoint &pos) override
 Deals falling/collision damage with terrain/creature at pos. More...
 
int hp_percentage () const override
 Returns overall % of HP remaining. More...
 
void regen (int rate_multiplier)
 Handles passive regeneration of pain and maybe hp. More...
 
void enforce_minimum_healing ()
 
itembest_quality_item (const quality_id &qual)
 get best quality item that this character has More...
 
virtual void update_health (int external_modifiers=0)
 Handles health fluctuations over time. More...
 
void update_body ()
 Updates all "biology" by one turn. More...
 
void update_body (const time_point &from, const time_point &to)
 Updates all "biology" as if time between from and to passed. More...
 
void update_stomach (const time_point &from, const time_point &to)
 Updates the stomach to give accurate hunger messages. More...
 
void update_needs (int rate_multiplier)
 Increases hunger, thirst, fatigue and stimulants wearing off. More...
 
needs_rates calc_needs_rates () const
 
void check_needs_extremes ()
 Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings. More...
 
bool is_hibernating () const
 Returns if the player has hibernation mutation and is asleep and well fed. More...
 
void update_bodytemp (const map &m, const weather_manager &weather)
 Maintains body temperature. More...
 
void temp_equalizer (const bodypart_id &bp1, const bodypart_id &bp2)
 Equalizes heat between body parts. More...
 
int blood_loss (const bodypart_id &bp) const
 Define blood loss (in percents) More...
 
void reset_bonuses () override
 Resets the value of all bonus fields to 0. More...
 
void reset_stats () override
 Resets stats, and applies effects in an idempotent manner. More...
 
void reset () override
 Handles stat and bonus reset. More...
 
void environmental_revert_effect ()
 
void reset_encumbrance ()
 Recalculates encumbrance cache. More...
 
int encumb (body_part bp) const
 Returns ENC provided by armor, etc. More...
 
units::mass get_weight () const override
 Returns body weight plus weight of inventory and worn/wielded items. More...
 
char_encumbrance_data get_encumbrance () const
 Get encumbrance for all body parts. More...
 
char_encumbrance_data get_encumbrance (const item &new_item) const
 Get encumbrance for all body parts as if new_item was also worn. More...
 
int extraEncumbrance (layer_level level, int bp) const
 Get encumbrance penalty per layer & body part. More...
 
bool is_wearing_power_armor (bool *hasHelmet=nullptr) const
 Returns true if the character is wearing power armor. More...
 
bool is_wearing_active_power_armor () const
 Returns true if the character is wearing active power. More...
 
bool is_wearing_active_optcloak () const
 Returns true if the player is wearing an active optical cloak. More...
 
bool in_climate_control ()
 Returns true if the player is in a climate controlled area or armor. More...
 
bool is_blind () const
 Returns true if the player isn't able to see. More...
 
bool is_invisible () const
 
int visibility (bool check_color=false, int stillness=0) const
 Checks is_invisible() as well as other factors. More...
 
float active_light () const
 Returns character luminosity based on the brightest active item they are carrying. More...
 
bool sees_with_specials (const Creature &critter) const
 
body_part_set exclusive_flag_coverage (const std::string &flag) const
 Bitset of all the body parts covered only with items with flag (or nothing) More...
 
bool move_effects (bool attacking) override
 Processes effects which may prevent the Character from moving (bear traps, crushed, etc.). More...
 
void wait_effects ()
 
bool movement_mode_is (character_movemode mode) const
 Check against the character's current movement mode. More...
 
character_movemode get_movement_mode () const
 
virtual void set_movement_mode (character_movemode mode)=0
 
void expose_to_disease (diseasetype_id dis_type)
 Determine if character is susceptible to dis_type and if so apply the symptoms. More...
 
void process_turn () override
 Handles end-of-turn processing. More...
 
void process_effects_internal () override
 Processes human-specific effects of effects before calling Creature::process_effects(). More...
 
void hardcoded_effects (effect &it)
 Handles the still hard-coded effects. More...
 
void process_one_effect (effect &it, bool is_new) override
 Processes human-specific effects of an effect. More...
 
void process_items ()
 Process active items. More...
 
void recalc_hp ()
 Recalculates HP after a change to max strength. More...
 
void calc_all_parts_hp (float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
 Sets hp for all body parts. More...
 
void recalc_sight_limits ()
 Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change: More...
 
float get_vision_threshold (float light_level) const
 Returns the apparent light level at which the player can see. More...
 
void flag_encumbrance ()
 Flag encumbrance for updating. More...
 
void check_item_encumbrance_flag ()
 Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating. More...
 
bool natural_attack_restricted_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag. More...
 
bool can_use_grab_break_tec (const item &weap) const
 Returns true if the player is able to use a grab breaking technique. More...
 
bool can_miss_recovery (const item &weap) const
 Returns true if the player is able to use a miss recovery technique. More...
 
bool is_quiet () const
 Returns true if the player has quiet melee attacks. More...
 
bool is_stealthy () const
 Returns true if the player has stealthy movement. More...
 
bool uncanny_dodge () override
 Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges. More...
 
bool block_ranged_hit (Creature *source, bodypart_id &bp_hit, damage_instance &dam) override
 Checks for chance that a ranged attack will hit other armor along the way. More...
 
bool block_hit (Creature *source, bodypart_id &bp_hit, damage_instance &dam) override
 Checks for valid block abilities and reduces damage accordingly. More...
 
itembest_shield ()
 Returns the best item for blocking with. More...
 
bool handle_melee_wear (item &shield, float wear_multiplier=1.0f)
 Calculates melee weapon wear-and-tear through use, returns true if item is destroyed. More...
 
matec_id pick_technique (Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
 Returns a random valid technique. More...
 
void perform_technique (const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
 
void melee_attack (Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
 Sets up a melee attack and handles melee attack function calls. More...
 
std::string melee_special_effects (Creature &t, damage_instance &d, item &weap)
 Handles combat effects, returns a string of any valid combat effect messages. More...
 
void perform_special_attacks (Creature &t, dealt_damage_instance &dealt_dam)
 Performs special attacks and their effects (poisonous, stinger, etc.) More...
 
void reach_attack (const tripoint &p)
 Handles reach melee attack on point p. More...
 
float stability_roll () const override
 Returns value of player's stable footing. More...
 
std::vector< special_attackmutation_attacks (Creature &t) const
 Returns a vector of valid mutation attacks. More...
 
float bonus_damage (bool random) const
 Returns the bonus bashing damage the player deals based on their stats. More...
 
float get_melee_hit_base () const
 Returns weapon skill. More...
 
float hit_roll () const override
 Returns the player's basic hit roll that is compared to the target's dodge roll. More...
 
double crit_chance (float roll_hit, float target_dodge, const item &weap) const
 Returns the chance to critical given a hit roll and target's dodge roll. More...
 
bool scored_crit (float target_dodge, const item &weap) const
 Returns true if the player scores a critical hit. More...
 
int attack_cost (const item &weap) const
 Returns cost (in moves) of attacking with given item (no modifiers, like stuck) More...
 
float get_hit_weapon (const item &weap) const
 Gets melee accuracy component from weapon+skills. More...
 
void roll_all_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds all 3 types of physical damage to instance. More...
 
void roll_bash_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total bash damage to the damage instance. More...
 
void roll_cut_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total cut damage to the damage instance. More...
 
void roll_stab_damage (bool crit, damage_instance &di, bool average, const item &weap) const
 Adds player's total stab damage to the damage instance. More...
 
void on_dodge (Creature *source, int difficulty) override
 This creature just dodged an attack - possibly special/ranged attack - from source. More...
 
void on_hit (Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
 This creature just got hit by an attack - possibly special/ranged attack - from source. More...
 
void did_hit (Creature &target)
 Handles special effects when the Character hits a Creature. More...
 
void apply_damage (Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
 Actually hurt the player, hurts a body_part directly, no armor reduction. More...
 
dealt_damage_instance deal_damage (Creature *source, bodypart_id bp, const damage_instance &d) override
 Calls Creature::deal_damage and handles damaged effects (waking up, etc.) More...
 
int reduce_healing_effect (const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
 Reduce healing effect intensity, return initial intensity of the effect. More...
 
void cough (bool harmful=false, int loudness=4)
 
void passive_absorb_hit (const bodypart_id &bp, damage_unit &du) const
 Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit. More...
 
void absorb_hit (const bodypart_id &bp, damage_instance &dam) override
 Runs through all bionics and armor on a part and reduces damage through their armor_absorb. More...
 
bool armor_absorb (damage_unit &du, item &armor)
 Reduces and mutates du, prints messages about armor taking damage. More...
 
float bionic_armor_bonus (const bodypart_id &bp, damage_type dt) const
 Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit. More...
 
int mabuff_armor_bonus (damage_type type) const
 Returns the armor bonus against given type from martial arts buffs. More...
 
std::map< bodypart_id, int > get_armor_fire (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns overall fire resistance. More...
 
bool has_trait (const trait_id &b) const override
 Returns true if the player has the entered trait. More...
 
bool has_base_trait (const trait_id &b) const
 Returns true if the player has the entered starting trait. More...
 
bool has_trait_flag (const std::string &b) const
 Returns true if player has a trait with a flag. More...
 
bool has_opposite_trait (const trait_id &flag) const
 Returns true if character has a trait which cancels the entered trait. More...
 
void toggle_trait (const trait_id &)
 Toggles a trait on the player and in their mutation list. More...
 
void set_mutation (const trait_id &)
 Add or removes a mutation on the player, but does not trigger mutation loss/gain effects. More...
 
void unset_mutation (const trait_id &)
 
void switch_mutations (const trait_id &switched, const trait_id &target, bool start_powered)
 Unset switched mutation and set target mutation instead. More...
 
void activate_mutation (const trait_id &mutation)
 
void deactivate_mutation (const trait_id &mut)
 
void mutation_spend_resources (const trait_id &mut)
 Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation). More...
 
bool can_mount (const monster &critter) const
 
void mount_creature (monster &z)
 
bool is_mounted () const
 
bool check_mount_will_move (const tripoint &dest_loc)
 
bool check_mount_is_spooked ()
 
void dismount ()
 
void forced_dismount ()
 
bool is_deaf () const
 
bool has_two_arms () const
 Returns true if the player has two functioning arms. More...
 
int get_working_arm_count () const
 Returns the number of functioning arms. More...
 
int get_working_leg_count () const
 Returns the number of functioning legs. More...
 
bool is_limb_disabled (const bodypart_id &limb) const
 Returns true if the limb is disabled (12.5% or less hp, or broken) More...
 
bool is_limb_broken (const bodypart_id &limb) const
 Returns true if the limb is broken. More...
 
bool can_run ()
 source of truth of whether a Character can run More...
 
void hurtall (int dam, Creature *source, bool disturb=true)
 Hurts all body parts for dam, no armor reduction. More...
 
int hitall (int dam, int vary, Creature *source)
 Harms all body parts for dam, with armor reduction. More...
 
void on_hurt (Creature *source, bool disturb=true)
 Handles effects that happen when the player is damaged and aware of the fact. More...
 
void heal (const bodypart_id &healed, int dam)
 Heals a body_part for dam. More...
 
void healall (int dam)
 Heals all body parts for dam. More...
 
hp_part body_window (const std::string &menu_header, bool show_all, bool precise, int normal_bonus, int head_bonus, int torso_bonus, float bleed, float bite, float infect, float bandage_power, float disinfectant_power) const
 Displays menu with body part hp, optionally with hp estimation after healing. More...
 
nc_color limb_color (const bodypart_id &bp, bool bleed, bool bite, bool infect) const
 
bool made_of (const material_id &m) const override
 
bool made_of_any (const std::set< material_id > &ms) const override
 
int posx () const override
 
int posy () const override
 
int posz () const override
 
void setx (int x)
 
void sety (int y)
 
void setz (int z)
 
void setpos (const tripoint &p) override
 
virtual tripoint global_square_location () const
 Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map. More...
 
tripoint global_sm_location () const
 Returns the location of the player in global submap coordinates. More...
 
tripoint_abs_omt global_omt_location () const
 Returns the location of the player in global overmap terrain coordinates. More...
 
void recalculate_enchantment_cache ()
 
void rebuild_mutation_cache ()
 
double bonus_from_enchantments (double base, enchant_vals::mod value, bool round=false) const
 Calculate bonus from enchantments for given base value. More...
 
bool has_mabuff (const mabuff_id &buff_id) const
 Returns true if the player has any martial arts buffs attached. More...
 
bool has_grab_break_tec () const override
 Returns true if the player has a grab breaking technique available. More...
 
float mabuff_tohit_bonus () const
 Returns the to hit bonus from martial arts buffs. More...
 
float mabuff_dodge_bonus () const
 Returns the dodge bonus from martial arts buffs. More...
 
int mabuff_block_bonus () const
 Returns the block bonus from martial arts buffs. More...
 
int mabuff_speed_bonus () const
 Returns the speed bonus from martial arts buffs. More...
 
int mabuff_arpen_bonus (damage_type type) const
 Returns the arpen bonus from martial arts buffs. More...
 
float mabuff_damage_mult (damage_type type) const
 Returns the damage multiplier to given type from martial arts buffs. More...
 
int mabuff_damage_bonus (damage_type type) const
 Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier. More...
 
int mabuff_attack_cost_penalty () const
 Returns the flat penalty to move cost of attacks. More...
 
float mabuff_attack_cost_mult () const
 Returns the multiplier on move cost of attacks. More...
 
void mutation_effect (const trait_id &mut)
 Handles things like removal of armor, etc. More...
 
void mutation_loss_effect (const trait_id &mut)
 Handles what happens when you lose a mutation. More...
 
bool has_active_mutation (const trait_id &b) const
 
void mutate ()
 Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way. More...
 
bool mutation_ok (const trait_id &mutation, bool force_good, bool force_bad) const
 Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing. More...
 
void mutate_category (const std::string &mut_cat)
 Picks a random valid mutation in a category and mutate_towards() it. More...
 
bool mutate_towards (std::vector< trait_id > muts, int num_tries=INT_MAX)
 Mutates toward one of the given mutations, upgrading or removing conflicts if necessary. More...
 
bool mutate_towards (const trait_id &mut)
 Mutates toward the entered mutation, upgrading or removing conflicts if necessary. More...
 
void remove_mutation (const trait_id &mut, bool silent=false)
 Removes a mutation, downgrading to the previous level if possible. More...
 
std::map< trait_id, float > mutation_chances () const
 Calculate percentage chances for mutations. More...
 
bool has_child_flag (const trait_id &flag) const
 Returns true if the player has the entered mutation child flag. More...
 
void remove_child_flag (const trait_id &flag)
 Removes the mutation's child flag from the player's list. More...
 
void set_highest_cat_level ()
 Recalculates mutation_category_level[] values for the player. More...
 
std::string get_highest_category () const
 Returns the highest mutation category. More...
 
void drench_mut_calc ()
 Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats) More...
 
void build_mut_dependency_map (const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
 Recursively traverses the mutation's prerequisites and replacements, building up a map. More...
 
bool is_category_allowed (const std::vector< std::string > &category) const
 Returns true if this category of mutation is allowed. More...
 
bool is_category_allowed (const std::string &category) const
 
bool is_weak_to_water () const
 
bool can_use_heal_item (const item &med) const
 Check for mutation disallowing the use of an healing item. More...
 
bool can_install_cbm_on_bp (const std::vector< bodypart_id > &bps) const
 
resistances mutation_armor (bodypart_id bp) const
 Returns resistances on a body part provided by mutations. More...
 
float mutation_armor (bodypart_id bp, damage_type dt) const
 
float mutation_armor (bodypart_id bp, const damage_unit &du) const
 
bool activate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic activation effects of the entered bionic, returns if anything activated. More...
 
std::vector< bionic_idget_bionics () const
 
bionicget_bionic_state (const bionic_id &id)
 Get state of bionic with given id. More...
 
std::pair< int, int > amount_of_storage_bionics () const
 Returns amount of Storage CBMs in the corpse. More...
 
bool has_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id. More...
 
bool has_active_bionic (const bionic_id &b) const
 Returns true if the player has the entered bionic id and it is powered on. More...
 
bool has_any_bionic () const
 Returns true if the player has any bionic. More...
 
bool can_fuel_bionic_with (const item &it) const
 Returns true if the character can fuel a bionic with the item. More...
 
std::vector< bionic_idget_bionic_fueled_with (const item &it) const
 Return bionic_id of bionics able to use it as fuel. More...
 
std::vector< bionic_idget_fueled_bionics () const
 Return bionic_id of fueled bionics. More...
 
bionic_id get_remote_fueled_bionic () const
 Returns bionic_id of first remote fueled bionic found. More...
 
bionic_id get_most_efficient_bionic (const std::vector< bionic_id > &bids) const
 Return bionic_id of bionic of most fuel efficient bionic. More...
 
std::vector< itype_idget_fuel_available (const bionic_id &bio) const
 Return list of available fuel for this bionic. More...
 
int get_fuel_type_available (const itype_id &fuel) const
 Return available space to store specified fuel. More...
 
int get_fuel_capacity (const itype_id &fuel) const
 Return available space to store specified fuel. More...
 
int get_total_fuel_capacity (const itype_id &fuel) const
 Return total space to store specified fuel. More...
 
void update_fuel_storage (const itype_id &fuel)
 Updates which bionic contain fuel and which is empty. More...
 
int get_mod_stat_from_bionic (const character_stat &Stat) const
 Get stat bonus from bionic. More...
 
void process_bionic (bionic &bio)
 Handles bionic effects over time of the entered bionic. More...
 
bool deactivate_bionic (bionic &bio, bool eff_only=false)
 Handles bionic deactivation effects of the entered bionic, returns if anything deactivated. More...
 
bool has_bionics () const
 Whether character has any bionics installed. More...
 
void clear_bionics ()
 Remove all bionics. More...
 
int get_used_bionics_slots (const bodypart_id &bp) const
 
int get_total_bionics_slots (const bodypart_id &bp) const
 
int get_free_bionics_slots (const bodypart_id &bp) const
 
bool has_enough_anesth (const itype *cbm, player &patient)
 Has enough anesthetic for surgery. More...
 
void introduce_into_anesthesia (const time_duration &duration, player &installer, bool needs_anesthesia)
 Handles process of introducing patient into anesthesia during Autodoc operations. More...
 
void remove_bionic (const bionic_id &b)
 Removes a bionic from my_bionics[]. More...
 
void add_bionic (const bionic_id &b)
 Adds a bionic to my_bionics[]. More...
 
float env_surgery_bonus (int radius)
 Calculate skill bonus from tiles in radius. More...
 
float bionics_adjusted_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate skill for (un)installing bionics. More...
 
int bionics_pl_skill (const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
 Calculate non adjusted skill for (un)installing bionics. More...
 
bool can_install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Is the installation possible. More...
 
std::map< bodypart_id, int > bionic_installation_issues (const bionic_id &bioid) const
 
bool install_bionics (const itype &type, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_install (bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
 Success or failure of installation happens here. More...
 
void do_damage_for_bionic_failure (int min_damage, int max_damage)
 
void bionics_install_failure (const std::string &installer, int difficulty, int success, float adjusted_skill)
 
bool can_uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Is The uninstallation possible. More...
 
bool uninstall_bionic (const bionic_id &b_id, player &installer, bool autodoc=false, int skill_level=-1)
 Initialize all the values needed to start the operation player_activity. More...
 
void perform_uninstall (bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
 Succes or failure of removal happens here. More...
 
void bionics_uninstall_failure (int difficulty, int success, float adjusted_skill)
 When a player fails the surgery. More...
 
bool uninstall_bionic (const bionic &target_cbm, monster &installer, player &patient, float adjusted_skill)
 Used by monster to perform surgery. More...
 
void bionics_uninstall_failure (monster &installer, player &patient, int difficulty, int success, float adjusted_skill)
 When a monster fails the surgery. More...
 
bool burn_fuel (bionic &bio, bool start=false)
 Convert fuel to bionic power. More...
 
void passive_power_gen (bionic &bio)
 Passively produce power from PERPETUAL fuel. More...
 
itype_id find_remote_fuel (bool look_only=false)
 Find fuel used by remote powered bionic. More...
 
int consume_remote_fuel (int amount)
 Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful). More...
 
void reset_remote_fuel ()
 
void heat_emission (bionic &bio, int fuel_energy)
 Handle heat from exothermic power generation. More...
 
float get_effective_efficiency (bionic &bio, float fuel_efficiency)
 Applies modifier to fuel_efficiency and returns the resulting efficiency. More...
 
units::energy get_power_level () const
 
units::energy get_max_power_level () const
 
void mod_power_level (const units::energy &npower)
 
void mod_max_power_level (const units::energy &npower_max)
 
void set_power_level (const units::energy &npower)
 
void set_max_power_level (const units::energy &npower_max)
 
bool is_max_power () const
 
bool has_power () const
 
bool has_max_power () const
 
bool enough_power_for (const bionic_id &bid) const
 
void conduct_blood_analysis () const
 
bool is_worn (const item &thing) const
 
virtual bool invoke_item (item *, const tripoint &pt)
 Asks how to use the item (if it has more than one use_method) and uses it. More...
 
virtual bool invoke_item (item *, const std::string &, const tripoint &pt)
 As above, but with a pre-selected method. More...
 
virtual bool invoke_item (item *)
 As above two, but with position equal to current position. More...
 
virtual bool invoke_item (item *, const std::string &)
 
virtual bool dispose_item (item_location &&obj, const std::string &prompt=std::string())
 Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves. More...
 
bool has_enough_charges (const item &it, bool show_msg) const
 Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges. More...
 
bool consume_charges (item &used, int qty)
 Consume charges of a tool or comestible item, potentially destroying it in the process. More...
 
int item_handling_cost (const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when handling (e.g. More...
 
int item_store_cost (const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
 Calculate (but do not deduct) the number of moves required when storing an item in a container. More...
 
int item_wear_cost (const item &it) const
 Calculate (but do not deduct) the number of moves required to wear an item. More...
 
int amount_worn (const itype_id &id) const
 Returns the amount of item ‘type’ that is currently worn. More...
 
std::vector< item_locationnearby (const std::function< bool(const item *, const item *)> &func, int radius=1) const
 Returns nearby items which match the provided predicate. More...
 
std::list< itemremove_worn_items_with (std::function< bool(item &)> filter)
 Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked). More...
 
iteminvlet_to_item (int invlet)
 Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet. More...
 
itemi_at (int position)
 
const itemi_at (int position) const
 
int get_item_position (const item *it) const
 Returns the item position (suitable for i_at or similar) of a specific item. More...
 
std::vector< item * > wielded_items ()
 Returns all equipped items that require a limb to be held. More...
 
std::vector< const item * > wielded_items () const
 
itemused_weapon ()
 Legacy code hack, don't use. More...
 
const itemused_weapon () const
 
itemprimary_weapon ()
 Legacy code hack, don't use. More...
 
const itemprimary_weapon () const
 
void set_primary_weapon (const item &new_weapon)
 Use this when primary weapon might not exist yet. More...
 
int i_add_to_container (const item &it, bool unloading)
 Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full. More...
 
itemi_add (item it, bool should_stack=true)
 
item i_rem (int pos)
 Remove a specific item from player possession. More...
 
item i_rem (const item *it)
 Remove a specific item from player possession. More...
 
void i_rem_keep_contents (int idx)
 
bool i_add_or_drop (item &it, int qty=1)
 Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded. More...
 
std::bitset< std::numeric_limits< char >::max()> allocated_invlets () const
 Only use for UI things. More...
 
bool has_active_item (const itype_id &id) const
 Whether the player carries an active item of the given item type. More...
 
item remove_weapon ()
 
bool has_mission_item (int mission_id) const
 
void remove_mission_items (int mission_id)
 
int throw_range (const item &) const
 Maximum thrown range with a given item, taking all active effects into account. More...
 
bool unarmed_attack () const
 True if unarmed or wielding a weapon with the UNARMED_WEAPON flag. More...
 
int best_nearby_lifting_assist () const
 Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range. More...
 
int best_nearby_lifting_assist (const tripoint &world_pos) const
 Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g. More...
 
std::vector< item * > inv_dump ()
 
units::mass weight_carried () const
 
units::volume volume_carried () const
 
units::mass weight_carried_reduced_by (const excluded_stacks &without) const
 
units::volume volume_carried_reduced_by (const excluded_stacks &without) const
 
units::mass weight_capacity () const override
 
units::volume volume_capacity () const
 
units::volume volume_capacity_reduced_by (const units::volume &mod, const excluded_stacks &without={}) const
 
bool can_pick_volume (const item &it) const
 
bool can_pick_volume (units::volume volume) const
 
bool can_pick_weight (const item &it, bool safe=true) const
 
bool can_pick_weight (units::mass weight, bool safe=true) const
 
bool can_use (const item &it, const item &context=item()) const
 Checks if character stats and skills meet minimum requirements for the item. More...
 
ret_val< bool > can_wear (const item &it, bool with_equip_change=false) const
 Check character capable of wearing an item. More...
 
std::optional< std::list< item >::iterator > wear_possessed (item &to_wear, bool interactive=true)
 Wear specified item. More...
 
std::optional< std::list< item >::iterator > wear_item (const item &to_wear, bool interactive=true)
 Wear a copy of specified item. More...
 
ret_val< bool > can_takeoff (const item &it, const std::list< item > *res=nullptr) const
 Check if character is capable of taking off given item. More...
 
bool takeoff (item &it, std::list< item > *res=nullptr)
 Take off an item. More...
 
bool is_armed () const
 Returns true if the character is wielding something. More...
 
ret_val< bool > can_wield (const item &it) const
 Check whether character is capable of wielding given item. More...
 
virtual bool wield (item &target)=0
 Removes currently wielded item (if any) and replaces it with the target item. More...
 
ret_val< bool > can_unwield (const item &it) const
 Check whether character is capable of unwielding given item. More...
 
bool unwield ()
 Removes currently wielded item (if any) More...
 
ret_val< bool > can_swap (const item &it) const
 Check player capable of swapping the side of a worn item. More...
 
void drop_invalid_inventory ()
 
std::list< item * > get_dependent_worn_items (const item &it) const
 Returns all items that must be taken off before taking off this item. More...
 
void drop (item_location loc, const tripoint &where)
 Drops an item to the specified location. More...
 
virtual void drop (const drop_locations &what, const tripoint &target, bool stash=false)
 
virtual bool has_artifact_with (art_effect_passive effect) const
 
bool is_wielding (const item &target) const
 
bool covered_with_flag (const std::string &flag, const body_part_set &parts) const
 
bool is_waterproof (const body_part_set &parts) const
 
int leak_level (const std::string &flag) const
 
bool can_reload (const item &it, const itype_id &ammo=itype_id()) const
 Whether a tool or gun is potentially reloadable (optionally considering a specific ammo) More...
 
int item_reload_cost (const item &it, const item &ammo, int qty) const
 Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo. More...
 
bool is_wearing (const item &itm) const
 Returns true if the player is wearing the item. More...
 
bool is_wearing (const itype_id &it) const
 Returns true if the player is wearing an item of this type. More...
 
bool is_wearing_on_bp (const itype_id &it, const bodypart_id &bp) const
 Returns true if the player is wearing the item on the given body part. More...
 
bool worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns true if the player is wearing an item with the given flag. More...
 
const itemitem_worn_with_flag (const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
 Returns the first worn item with a given flag. More...
 
std::vector< std::string > get_overlay_ids () const
 Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest". More...
 
int get_skill_level (const skill_id &ident) const
 
int get_skill_level (const skill_id &ident, const item &context) const
 
const SkillLevelMapget_all_skills () const
 
SkillLevelget_skill_level_object (const skill_id &ident)
 
const SkillLevelget_skill_level_object (const skill_id &ident) const
 
void set_skill_level (const skill_id &ident, int level)
 
void mod_skill_level (const skill_id &ident, int delta)
 
bool meets_skill_requirements (const std::map< skill_id, int > &req, const item &context=item()) const
 Checks whether the character's skills meet the required. More...
 
bool meets_skill_requirements (const construction &con) const
 Checks whether the character's skills meet the required. More...
 
bool meets_stat_requirements (const item &it) const
 Checks whether the character's stats meets the stats required by the item. More...
 
bool meets_requirements (const item &it, const item &context=item()) const
 Checks whether the character meets overall requirements to be able to use the item. More...
 
std::string enumerate_unmet_requirements (const item &it, const item &context=item()) const
 Returns a string of missed requirements (both stats and skills) More...
 
int rust_rate () const
 Returns the player's skill rust rate. More...
 
void practice (const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
 This handles giving xp for a skill. More...
 
int read_speed (bool return_stat_effect=true) const
 Returns the player's reading speed. More...
 
time_point get_time_died () const
 return the calendar::turn the character expired More...
 
void set_time_died (const time_point &time)
 set the turn the turn the character died if not already done More...
 
void die (Creature *nkiller) override
 Empty function. More...
 
std::string get_name () const override
 
std::vector< std::string > get_grammatical_genders () const override
 
template<typename ... Args>
bool query_yn (const char *const msg, Args &&... args) const
 It is supposed to hide the query_yn to simplify player vs. More...
 
virtual bool query_yn (const std::string &msg) const =0
 
bool is_immune_field (const field_type_id &fid) const override
 Returns true if we are immune to the field type with the given fid. More...
 
bool is_elec_immune () const override
 Returns true is the player is protected from electric shocks. More...
 
bool is_immune_effect (const efftype_id &) const override
 Returns true if the player is immune to this kind of effect. More...
 
bool is_immune_damage (damage_type) const override
 Returns true if the player is immune to this kind of damage. More...
 
bool is_rad_immune () const
 Returns true if the player is protected from radiation. More...
 
bool is_throw_immune () const
 Returns true if the player is immune to throws. More...
 
bool has_nv ()
 Returns true if the player has some form of night vision. More...
 
float rest_quality () const
 Returns >0 if character is sitting/lying and relatively inactive. More...
 
float healing_rate (float at_rest_quality) const
 Average hit points healed per turn. More...
 
float healing_rate_medicine (float at_rest_quality, const bodypart_id &bp) const
 Average hit points healed per turn from healing effects. More...
 
float mutation_value (const std::string &val) const
 Goes over all mutations, gets min and max of a value with given name. More...
 
social_modifiers get_mutation_social_mods () const
 Goes over all mutations, returning the sum of the social modifiers. More...
 
nc_color basic_symbol_color () const override
 
nc_color symbol_color () const override
 
std::string extended_description () const override
 
void pick_name (bool bUseDefault=false)
 Returns a random name from NAMES_*. More...
 
std::vector< trait_idget_base_traits () const
 Get the idents of all base traits. More...
 
std::vector< trait_idget_mutations (bool include_hidden=true) const
 Get the idents of all traits/mutations. More...
 
const std::bitset< NUM_VISION_MODES > & get_vision_modes () const
 
void clear_skills ()
 Clear the skills map, setting all levels to 0. More...
 
void clear_mutations ()
 Empties the trait and mutations lists. More...
 
bool crossed_threshold () const
 Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold. More...
 
void add_addiction (add_type type, int strength)
 Adds an addiction to the player. More...
 
void rem_addiction (add_type type)
 Removes an addition from the player. More...
 
bool has_addiction (add_type type) const
 Returns true if the player has an addiction of the specified type. More...
 
int addiction_level (add_type type) const
 Returns the intensity of the specified addiction. More...
 
void start_hauling ()
 
void stop_hauling ()
 
bool is_hauling () const
 
bool has_item_with_flag (const std::string &flag, bool need_charges=false) const
 
std::vector< const item * > all_items_with_flag (const std::string &flag) const
 All items that have the given flag (item::has_flag). More...
 
bool has_charges (const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
 
std::list< itemuse_amount (itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool use_charges_if_avail (const itype_id &it, int quantity)
 
std::list< itemuse_charges (const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
 
bool has_fire (int quantity) const
 
void use_fire (int quantity)
 
void assign_stashed_activity ()
 
bool check_outbounds_activity (const player_activity &act, bool check_only=false)
 
void assign_activity (const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
 Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming. More...
 
void assign_activity (const player_activity &act, bool allow_resume=true)
 Assigns activity to player, possibly resuming old activity if it's similar enough. More...
 
bool has_activity (const activity_id &type) const
 Check if player currently has a given activity. More...
 
bool has_activity (const std::vector< activity_id > &types) const
 Check if player currently has any of the given activities. More...
 
void resume_backlog_activity ()
 
void cancel_activity ()
 
void cancel_stashed_activity ()
 
player_activity get_stashed_activity () const
 
void set_stashed_activity (const player_activity &act, const player_activity &act_back=player_activity())
 
bool has_stashed_activity () const
 
void initialize_stomach_contents ()
 
float metabolic_rate_base () const
 Stable base metabolic rate due to traits. More...
 
float metabolic_rate () const
 Current metabolic rate due to traits, hunger, speed, etc. More...
 
std::string get_weight_string () const
 
int get_max_healthy () const
 
float bmi () const
 
int bmr () const
 
void reset_chargen_attributes ()
 
int base_age () const
 
void set_base_age (int age)
 
void mod_base_age (int mod)
 
int age () const
 
std::string age_string () const
 
int base_height () const
 
void set_base_height (int height)
 
void mod_base_height (int mod)
 
std::string height_string () const
 
int height () const
 
units::mass bodyweight () const
 
units::mass bionics_weight () const
 
int get_armor_bash (bodypart_id bp) const override
 Returns overall bashing resistance for the body_part. More...
 
int get_armor_cut (bodypart_id bp) const override
 Returns overall cutting resistance for the body_part. More...
 
int get_armor_bullet (bodypart_id bp) const override
 Returns overall bullet resistance for the body_part. More...
 
int get_armor_bash_base (bodypart_id bp) const override
 Returns bashing resistance from the creature and armor only. More...
 
int get_armor_cut_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_armor_bullet_base (bodypart_id bp) const override
 Returns cutting resistance from the creature and armor only. More...
 
int get_env_resist (bodypart_id bp) const override
 Returns overall env_resist on a body_part. More...
 
int get_armor_acid (bodypart_id bp) const
 Returns overall acid resistance for the body part. More...
 
int get_armor_type (damage_type dt, bodypart_id bp) const override
 Returns overall resistance to given type on the bod part. More...
 
std::map< bodypart_id, int > get_all_armor_type (damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 
int get_stim () const
 
void set_stim (int new_stim)
 
void mod_stim (int mod)
 
int get_rad () const
 
void set_rad (int new_rad)
 
void mod_rad (int mod)
 
int get_stamina () const
 
int get_stamina_max () const
 
void set_stamina (int new_stamina)
 
void mod_stamina (int mod)
 
void burn_move_stamina (int moves)
 
float stamina_move_cost_modifier () const
 
void update_stamina (int turns)
 Regenerates stamina. More...
 
void on_item_wear (const item &it)
 Called when an item is worn. More...
 
void on_item_takeoff (const item &it)
 Called when an item is taken off. More...
 
void on_worn_item_washed (const item &it)
 Called when an item is washed. More...
 
void on_effect_int_change (const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
 Called when effect intensity has been changed. More...
 
void on_mutation_gain (const trait_id &mid)
 Called when a mutation is gained. More...
 
void on_mutation_loss (const trait_id &mid)
 Called when a mutation is lost. More...
 
void on_stat_change (const std::string &stat, int value) override
 Called when a stat is changed. More...
 
void on_worn_item_transform (const item &old_it, const item &new_it)
 Called when a worn item is transformed. More...
 
void wake_up ()
 Removes "sleep" and "lying_down". More...
 
int get_shout_volume () const
 
void shout (std::string msg="", bool order=false)
 
void vomit ()
 Handles Character vomiting effects. More...
 
void healed_bp (int bp, int amount)
 
int adjust_for_focus (int amount) const
 
void update_type_of_scent (bool init=false)
 
void update_type_of_scent (const trait_id &mut, bool gain=true)
 
void set_type_of_scent (const scenttype_id &id)
 
scenttype_id get_type_of_scent () const
 
void restore_scent ()
 restore scent after masked_scent effect run out or is removed by water More...
 
void mod_painkiller (int npkill)
 Modifies intensity of painkillers
More...
 
void set_painkiller (int npkill)
 Sets intensity of painkillers
More...
 
int get_painkiller () const
 Returns intensity of painkillers
More...
 
void react_to_felt_pain (int intensity)
 
void mod_pain (int npain) override
 Modifies a pain value by player traits before passing it to Creature::mod_pain() More...
 
void set_pain (int npain) override
 Sets new intensity of pain an reacts to it. More...
 
int get_perceived_pain () const override
 Returns perceived pain (reduced with painkillers) More...
 
void spores ()
 
void blossoms ()
 
void rooted_message () const
 Handles rooting effects. More...
 
void rooted ()
 
void fall_asleep ()
 Adds "sleep" to the player. More...
 
void fall_asleep (const time_duration &duration)
 
std::string is_snuggling () const
 Checks to see if the player is using floor items to keep warm, and return the name of one such item if so. More...
 
float power_rating () const override
 Returns an approximation of the creature's strength. More...
 
float speed_rating () const override
 Returns an approximate number of tiles this creature can travel per turn. More...
 
itemitem_with_best_of_quality (const quality_id &qid)
 Returns the item in the player's inventory with the highest of the specified quality. More...
 
bool sees_with_infrared (const Creature &critter) const
 Check whether the this player can see the other creature with infrared. More...
 
void place_corpse ()
 
void place_corpse (const tripoint_abs_omt &om_target)
 
int run_cost (int base_cost, bool diag=false) const
 Returns the player's modified base movement cost. More...
 
const pathfinding_settingsget_pathfinding_settings () const override
 Returns settings for pathfinding. More...
 
std::set< tripointget_path_avoid () const override
 Returns a set of points we do not want to path through. More...
 
std::vector< Creature * > get_hostile_creatures (int range) const
 Get all hostile creatures currently visible to this player. More...
 
std::vector< Creature * > get_visible_creatures (int range) const
 Returns all creatures that this player can see and that are in the given range. More...
 
std::string visible_mutations (int visibility_cap) const
 Returns an enumeration of visible mutations with colors. More...
 
player_activity get_destination_activity () const
 
void set_destination_activity (const player_activity &new_destination_activity)
 
void clear_destination_activity ()
 
std::map< bodypart_id, int > warmth (const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
 Returns warmth provided by armor, etc. More...
 
bool can_use_floor_warmth () const
 Can the player lie down and cover self with blankets etc. More...
 
int floor_warmth (const tripoint &pos) const
 Final warmth from the floor. More...
 
int bodytemp_modifier_traits (bool overheated) const
 Correction factor of the body temperature due to traits and mutations. More...
 
int bodytemp_modifier_traits_floor () const
 Correction factor of the body temperature due to traits and mutations for player lying on the floor. More...
 
int temp_corrected_by_climate_control (int temperature) const
 Value of the body temperature corrected by climate control. More...
 
bool in_sleep_state () const override
 
void update_vitamins (const vitamin_id &vit)
 Set vitamin deficiency/excess disease states dependent upon current vitamin levels. More...
 
int vitamin_get (const vitamin_id &vit) const
 Check current level of a vitamin. More...
 
bool vitamin_set (const vitamin_id &vit, int qty)
 Sets level of a vitamin or returns false if id given in vit does not exist. More...
 
int vitamin_mod (const vitamin_id &vit, int qty, bool capped=true)
 Add or subtract vitamins from character storage pools. More...
 
void vitamins_mod (const std::map< vitamin_id, int > &, bool capped=true)
 
time_duration vitamin_rate (const vitamin_id &vit) const
 Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects. More...
 
int nutrition_for (const item &comest) const
 Handles the nutrition value for a comestible. More...
 
ret_val< edible_ratingcan_eat (const item &food) const
 Can the food be [theoretically] eaten no matter the consequen ces? More...
 
ret_val< edible_ratingwill_eat (const item &food, bool interactive=false) const
 Same as can_eat, but takes consequences into account. More...
 
bool can_feed_furnace_with (const item &it) const
 Determine character's capability of recharging their CBMs. More...
 
rechargeable_cbm get_cbm_rechargeable_with (const item &it) const
 
int get_acquirable_energy (const item &it, rechargeable_cbm cbm) const
 
int get_acquirable_energy (const item &it) const
 
bool feed_furnace_with (item &it)
 Recharge CBMs whenever possible. More...
 
bool fuel_bionic_with (item &it)
 
void modify_stimulation (const islot_comestible &comest)
 Used to apply stimulation modifications from food and medication. More...
 
void modify_fatigue (const islot_comestible &comest)
 Used to apply fatigue modifications from food and medication. More...
 
void modify_radiation (const islot_comestible &comest)
 Used to apply radiation from food and medication. More...
 
void modify_addiction (const islot_comestible &comest)
 Used to apply addiction modifications from food and medication. More...
 
void modify_health (const islot_comestible &comest)
 Used to apply health modifications from food and medication. More...
 
bool consume_effects (item &food)
 Handles the effects of consuming an item. More...
 
bool can_consume (const item &it) const
 Check character's capability of consumption overall. More...
 
bool can_estimate_rot () const
 True if the character has enough skill (in cooking or survival) to estimate time to rot. More...
 
bool can_consume_as_is (const item &it) const
 Check whether character can consume this very item. More...
 
bool can_consume_for_bionic (const item &it) const
 
itemget_consumable_from (item &it) const
 Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise. More...
 
void consume (item_location loc)
 Consume item (food, fuel, medicine, ...) at given location loc . More...
 
bool consume_item (item &target)
 Consume given item (food, fuel, medicine, ...). More...
 
bool consume_med (item &target)
 Consume an item as medication. More...
 
bool eat (item &food, bool force=false)
 Used for eating entered comestible, returns true if comestible is successfully eaten. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Get calorie & vitamin contents for a comestible, taking into account character traits. More...
 
std::pair< nutrients, nutrientscompute_nutrient_range (const itype_id &, const cata::flat_set< std::string > &extra_flags={}) const
 Same, but across arbitrary recipes. More...
 
morale_type allergy_type (const item &food) const
 Returns allergy type or MORALE_NULL if not allergic for this character. More...
 
nutrients compute_effective_nutrients (const item &) const
 
bool wearing_something_on (const bodypart_id &bp) const
 Returns true if the character is wearing something on the entered body part. More...
 
bool is_wearing_helmet () const
 Returns true if the character is wearing something occupying the helmet slot. More...
 
int head_cloth_encumbrance () const
 Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head. More...
 
double armwear_factor () const
 Same as footwear factor, but for arms. More...
 
int shoe_type_count (const itype_id &it) const
 Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither. More...
 
double footwear_factor () const
 Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither. More...
 
bool is_wearing_shoes (const side &which_side=side::BOTH) const
 Returns true if the player is wearing something on their feet that is not SKINTIGHT. More...
 
bool change_side (item &it, bool interactive=true)
 Swap side on which item is worn; returns false on fail. More...
 
bool change_side (item_location &loc, bool interactive=true)
 
bool get_check_encumbrance () const
 
void set_check_encumbrance (bool new_check)
 
void update_morale ()
 Ticks down morale counters and removes them. More...
 
void apply_persistent_morale ()
 Ensures persistent morale effects are up-to-date. More...
 
void modify_morale (item &food, int nutr=0)
 Used to apply morale modifications from food and medication. More...
 
int get_morale_level () const
 
void add_morale (const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
 
bool has_morale (const morale_type &type) const
 
int get_morale (const morale_type &type) const
 
void rem_morale (const morale_type &type)
 
void clear_morale ()
 
bool has_morale_to_read () const
 
bool has_morale_to_craft () const
 
const inventorycrafting_inventory (bool clear_path)
 
const inventorycrafting_inventory (const tripoint &src_pos=tripoint_zero, int radius=PICKUP_RANGE, bool clear_path=true)
 
void invalidate_crafting_inventory ()
 
const recipe_subsetget_learned_recipes () const
 Returns all known recipes. More...
 
bool knows_recipe (const recipe *rec) const
 
void learn_recipe (const recipe *rec)
 
bool can_learn_by_disassembly (const recipe &rec) const
 
bool check_and_recover_morale ()
 Checks permanent morale for consistency and recovers it when an inconsistency is found. More...
 
std::pair< int, int > fun_for (const item &comest) const
 Handles the enjoyability value for a comestible. More...
 
void suffer ()
 Handles a large number of timers decrementing and other randomized effects. More...
 
bool irradiate (float rads, bool bypass=false)
 Handles mitigation and application of radiation. More...
 
void sound_hallu ()
 Creates an auditory hallucination. More...
 
void drench (int saturation, const body_part_set &flags, bool ignore_waterproof)
 Drenches the player with water, saturation is the percent gotten wet. More...
 
void apply_wetness_morale (int temperature)
 Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature. More...
 
std::vector< std::string > short_description_parts () const
 
std::string short_description () const
 
int print_info (const catacurses::window &w, int vStart, int vLines, int column) const override
 Write information about this creature. More...
 
bool can_hear (const tripoint &source, int volume) const
 
float hearing_ability () const
 
bool knows_trap (const tripoint &pos) const
 
void add_known_trap (const tripoint &pos, const trap &t)
 
bool avoid_trap (const tripoint &pos, const trap &tr) const override
 Called when character triggers a trap, returns true if they don't set it off. More...
 
nc_color bodytemp_color (int bp) const
 Define color for displaying the body temperature. More...
 
bool sees (const tripoint &t, bool is_player=false, int range_mod=0) const override
 
bool sees (const Creature &critter) const override
 The functions check whether this creature can see the target. More...
 
Attitude attitude_to (const Creature &other) const override
 Attitude (of this creature) towards another creature. More...
 
int get_lowest_hp () const
 
bool has_weapon () const override
 
void shift_destination (point shift)
 
void set_destination (const std::vector< tripoint > &route, const player_activity &new_destination_activity=player_activity())
 
void clear_destination ()
 
bool has_distant_destination () const
 
bool is_auto_moving () const
 
bool has_destination () const
 
bool has_destination_activity () const
 
void start_destination_activity ()
 
std::vector< tripoint > & get_auto_move_route ()
 
action_id get_next_auto_move_direction ()
 
bool defer_move (const tripoint &next)
 
std::map< bodypart_id, float > bodypart_exposure ()
 Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked). More...
 
void set_underwater (bool x) override
 
void clear_npc_ai_info_cache (npc_ai_info key) const
 
void set_npc_ai_info_cache (npc_ai_info key, double val) const
 
std::optional< double > get_npc_ai_info_cache (npc_ai_info key) const
 
safe_reference< Characterget_safe_reference ()
 
bool pour_into (item &container, item &liquid)
 Try to pour the given liquid into the given container/vehicle. More...
 
bool pour_into (vehicle &veh, item &liquid)
 
- Public Member Functions inherited from Creature
virtual ~Creature ()
 
virtual bool is_player () const
 
virtual bool is_avatar () const
 
virtual bool is_npc () const
 
virtual bool is_monster () const
 
virtual monsteras_monster ()
 
virtual const monsteras_monster () const
 
virtual npcas_npc ()
 
virtual const npcas_npc () const
 
virtual playeras_player ()
 
virtual const playeras_player () const
 
virtual avataras_avatar ()
 
virtual const avataras_avatar () const
 
virtual bool is_fake () const
 Returns true for non-real Creatures used temporarily; i.e. More...
 
virtual void set_fake (bool fake_value)
 Sets a Creature's fake boolean. More...
 
virtual void bleed () const
 Adds an appropriate blood splatter. More...
 
Creatureauto_find_hostile_target (int range, int &boo_hoo, int area=0)
 For fake-players (turrets, mounted turrets) this functions chooses a target. More...
 
double ranged_target_size () const
 Size of the target this creature presents to ranged weapons. More...
 
void knock_back_from (const tripoint &p)
 
int size_melee_penalty () const
 
virtual int deal_melee_attack (Creature *source, int hitroll)
 
virtual void deal_melee_hit (Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
 
virtual void deal_projectile_attack (Creature *source, dealt_projectile_attack &attack)
 Attempts to harm a creature with a projectile. More...
 
virtual void deal_damage_handle_type (const damage_unit &du, bodypart_id bp, int &damage, int &pain)
 
virtual bool digging () const
 
virtual bool is_underwater () const
 
virtual bool is_hallucination () const =0
 
bool is_dangerous_fields (const field &fld) const
 Returns true if there is a field in the field set that is dangerous to us. More...
 
bool is_dangerous_field (const field_entry &entry) const
 Returns true if the given field entry is dangerous to us. More...
 
void check_dead_state ()
 This function checks the creatures is_dead_state and (if true) calls die. More...
 
void add_effect (const effect &eff, bool force=false, bool deferred=false)
 
virtual void add_effect (const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false)
 Adds or modifies an effect. More...
 
void add_effect (const efftype_id &eff_id, const time_duration &dur, body_part bp=num_bp, int intensity=0, bool force=false, bool deferred=false)
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
 Gives chance to save via environmental resist, returns false if resistance was successful. More...
 
bool add_env_effect (const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp, bool REMOVED, int intensity=1, bool force=false)=delete
 
bool remove_effect (const efftype_id &eff_id, body_part bp=num_bp)
 Removes a listed effect. More...
 
virtual bool remove_effect (const efftype_id &eff_id, const bodypart_str_id &bp)
 
void clear_effects ()
 Remove all effects. More...
 
bool has_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Check if creature has the matching effect. More...
 
bool has_effect (const efftype_id &eff_id, const bodypart_str_id &bp) const
 
bool has_effect_with_flag (const std::string &flag, body_part bp=num_bp) const
 Check if creature has any effect with the given flag. More...
 
const effectget_effect (const efftype_id &eff_id, body_part bp=num_bp) const
 Return the effect that matches the given arguments exactly. More...
 
effectget_effect (const efftype_id &eff_id, body_part bp=num_bp)
 
std::vector< const effect * > get_all_effects_of_type (const efftype_id &eff_id) const
 Returns pointers to all effects matching given type. More...
 
std::vector< effect * > get_all_effects_of_type (const efftype_id &eff_id)
 
time_duration get_effect_dur (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the duration of the matching effect. More...
 
int get_effect_int (const efftype_id &eff_id, body_part bp=num_bp) const
 Returns the intensity of the matching effect. More...
 
bool resists_effect (const effect &e) const
 Returns true if the creature resists an effect. More...
 
void set_value (const std::string &key, const std::string &value)
 
void remove_value (const std::string &key)
 
std::string get_value (const std::string &key) const
 
void process_effects ()
 Processes through all the effects on the Creature. More...
 
virtual void mod_pain_noresist (int npain)
 
virtual int get_pain () const
 
int get_moves () const
 
void mod_moves (int nmoves)
 
void set_moves (int nmoves)
 
virtual Creatureget_killer () const
 
virtual int get_num_blocks () const
 
virtual int get_num_dodges () const
 
virtual int get_num_blocks_bonus () const
 
virtual int get_num_dodges_bonus () const
 
virtual int get_num_dodges_base () const
 
virtual int get_armor_bash_bonus () const
 
virtual int get_armor_cut_bonus () const
 
virtual int get_armor_bullet_bonus () const
 
virtual float get_hit () const
 
virtual int get_hp (const bodypart_id &bp) const
 
virtual int get_hp () const
 
virtual int get_hp_max (const bodypart_id &bp) const
 
virtual int get_hp_max () const
 
virtual bool has_flag (const m_flag) const
 
anatomy_id get_anatomy () const
 
void set_anatomy (anatomy_id anat)
 
bodypart_id get_random_body_part (bool main=false) const
 
std::vector< bodypart_idget_all_body_parts (bool only_main=false) const
 Returns body parts this creature have. More...
 
const std::map< bodypart_str_id, bodypart > & get_body () const
 
void set_body ()
 
bodypartget_part (const bodypart_id &id)
 
const bodypartget_part (const bodypart_id &id) const
 
int get_part_hp_cur (const bodypart_id &id) const
 
int get_part_hp_max (const bodypart_id &id) const
 
int get_part_healed_total (const bodypart_id &id) const
 
void set_part_hp_cur (const bodypart_id &id, int set)
 
void set_part_hp_max (const bodypart_id &id, int set)
 
void set_part_healed_total (const bodypart_id &id, int set)
 
void mod_part_hp_cur (const bodypart_id &id, int mod)
 
void mod_part_hp_max (const bodypart_id &id, int mod)
 
void mod_part_healed_total (const bodypart_id &id, int mod)
 
void set_all_parts_hp_cur (int set)
 
void set_all_parts_hp_to_max ()
 
virtual int get_speed_base () const
 
virtual int get_speed_bonus () const
 
virtual float get_speed_mult () const
 
virtual int get_block_bonus () const
 
virtual float get_dodge_bonus () const
 
virtual float get_hit_bonus () const
 
virtual void set_num_blocks_bonus (int nblocks)
 
virtual void mod_num_dodges_bonus (int ndodges)
 
virtual void set_armor_bash_bonus (int nbasharm)
 
virtual void set_armor_cut_bonus (int ncutarm)
 
virtual void set_armor_bullet_bonus (int nbulletarm)
 
virtual void set_speed_base (int nspeed)
 
virtual void set_speed_bonus (int nspeed)
 
virtual void set_speed_mult (float nspeed)
 
virtual void set_block_bonus (int nblock)
 
virtual void mod_speed_bonus (int nspeed)
 
virtual void mod_speed_mult (float nspeed)
 
virtual void mod_block_bonus (int nblock)
 
virtual void set_dodge_bonus (float ndodge)
 
virtual void set_hit_bonus (float nhit)
 
virtual void mod_dodge_bonus (float ndodge)
 
virtual void mod_hit_bonus (float nhit)
 
void draw (const catacurses::window &w, point origin, bool inverted) const
 
void draw (const catacurses::window &w, const tripoint &origin, bool inverted) const
 
void describe_infrared (std::vector< std::string > &buf) const
 Describe this creature as seen by the avatar via infrared vision. More...
 
void describe_specials (std::vector< std::string > &buf) const
 Describe this creature as detected by the avatar's special senses. More...
 
virtual void add_msg_if_player (const std::string &) const
 
virtual void add_msg_if_player (const game_message_params &, const std::string &) const
 
void add_msg_if_player (const translation &) const
 
void add_msg_if_player (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_player (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_player (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_if_npc (const std::string &) const
 
virtual void add_msg_if_npc (const game_message_params &, const std::string &) const
 
void add_msg_if_npc (const translation &) const
 
void add_msg_if_npc (const game_message_params &, const translation &) const
 
template<typename ... Args>
void add_msg_if_npc (const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const translation &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const char *const msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const std::string &msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_if_npc (const game_message_params &params, const translation &msg, Args &&... args) const
 
virtual void add_msg_player_or_npc (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_npc (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_npc (const translation &, const translation &) const
 
void add_msg_player_or_npc (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_npc (const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const char *const player_msg, const char *const npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const std::string &player_msg, const std::string &npc_msg, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_npc (const game_message_params &params, const translation &player_msg, const translation &npc_msg, Args &&... args) const
 
virtual void add_msg_player_or_say (const std::string &, const std::string &) const
 
virtual void add_msg_player_or_say (const game_message_params &, const std::string &, const std::string &) const
 
void add_msg_player_or_say (const translation &, const translation &) const
 
void add_msg_player_or_say (const game_message_params &, const translation &, const translation &) const
 
template<typename ... Args>
void add_msg_player_or_say (const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const char *const player_msg, const char *const npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const std::string &player_msg, const std::string &npc_speech, Args &&... args) const
 
template<typename ... Args>
void add_msg_player_or_say (const game_message_params &params, const translation &player_msg, const translation &npc_speech, Args &&... args) const
 
virtual bool is_symbol_highlighted () const
 
effects_map get_all_effects () const
 
body_part select_body_part (Creature *source, int hit_roll) const
 
std::string replace_with_npc_name (std::string input) const
 This function replaces the "<npcname>" substring with the disp_name of this creature. More...
 
- Public Member Functions inherited from visitable< Character >
VisitResponse visit_items (const std::function< VisitResponse(item *, item *)> &func)
 Traverses this object and any child items contained using a visitor pattern. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *, const item *)> &func) const
 
VisitResponse visit_items (const std::function< VisitResponse(item *)> &func)
 Lightweight version which provides only the current node. More...
 
VisitResponse visit_items (const std::function< VisitResponse(const item *)> &func) const
 
itemfind_parent (const item &it)
 Determine the immediate parent container (if any) for an item. More...
 
const itemfind_parent (const item &it) const
 
std::vector< item * > parents (const item &it)
 Returns vector of parent containers (if any) starting with the innermost. More...
 
std::vector< const item * > parents (const item &it) const
 
bool has_item (const item &it) const
 Returns true if this visitable instance contains the item. More...
 
bool has_item_with (const std::function< bool(const item &)> &filter) const
 Returns true if any item (including those within a container) matches the filter. More...
 
bool has_quality (const quality_id &qual, int level=1, int qty=1) const
 Returns true if instance has amount (or more) items of at least quality level. More...
 
int max_quality (const quality_id &qual) const
 Return maximum tool quality level provided by instance or INT_MIN if not found. More...
 
int charges_of (const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
 Count maximum available charges from this instance and any contained items. More...
 
int amount_of (const itype_id &what, bool pseudo=true, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >) const
 Count items matching id including both this instance and any contained items. More...
 
bool has_amount (const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
 Check instance provides at least qty of an item (. More...
 
std::vector< item * > items_with (const std::function< bool(const item &)> &filter)
 Returns all items (including those within a container) matching the filter. More...
 
std::vector< const item * > items_with (const std::function< bool(const item &)> &filter) const
 
std::list< itemremove_items_with (const std::function< bool(const item &)> &filter, int count=INT_MAX)
 Removes items contained by this instance which match the filter. More...
 
item remove_item (item &it)
 Removes and returns the item which must be contained by this instance. More...
 

Static Public Member Functions

static hp_part bp_to_hp (body_part bp)
 Converts a body_part to an hp_part. More...
 
static body_part hp_to_bp (hp_part hpart)
 Converts an hp_part to a body_part. More...
 
static int worn_position_to_index (int position)
 
static int floor_bedding_warmth (const tripoint &pos)
 Warmth from terrain, furniture, vehicle furniture and traps. More...
 
static int floor_item_warmth (const tripoint &pos)
 Warmth from clothing on the floor. More...
 
- Static Public Member Functions inherited from Creature
static std::string attitude_raw_string (Attitude att)
 Simplified attitude string for unlocalized needs. More...
 
static const std::pair< translation, nc_color > & get_attitude_ui_data (Attitude att)
 Creature Attitude as String and color. More...
 
static void load_hit_range (const JsonObject &)
 
static void reset_hit_range ()
 

Public Attributes

bool death_drops = true
 
bool controlling_vehicle = false
 
int str_max = 0
 
int dex_max = 0
 
int int_max = 0
 
int per_max = 0
 
int str_cur = 0
 
int dex_cur = 0
 
int int_cur = 0
 
int per_cur = 0
 
int blocks_left = 0
 
int dodges_left = 0
 
double recoil = MAX_RECOIL
 
profession_id prof
 
std::string custom_profession
 
bool reach_attacking = false
 
pimpl< known_magicmagic
 
std::string name
 
bool male = true
 
std::list< itemworn
 
std::array< int, num_hp_partsdamage_bandaged
 
std::array< int, num_hp_partsdamage_disinfected
 
bool nv_cached = false
 
bool in_vehicle = false
 
bool hauling = false
 
player_activity stashed_outbounds_activity
 
player_activity stashed_outbounds_backlog
 
player_activity activity
 
std::list< player_activitybacklog
 
std::optional< tripointdestination_point
 
inventory inv
 
itype_id last_item
 
int scent = 0
 
pimpl< bionic_collectionmy_bionics
 
pimpl< character_martial_artsmartial_arts_data
 
stomach_contents stomach
 
pimpl< consumption_history_tconsumption_history
 
int oxygen = 0
 
int tank_plut = 0
 
int reactor_plut = 0
 
int slow_rad = 0
 
int focus_pool = 0
 
int cash = 0
 
std::set< character_idfollower_ids
 
item_location ammo_location
 
std::set< tripoint_abs_omtcamps
 
time_point cached_time
 
std::vector< addictionaddictions
 
shared_ptr_fast< monstermounted_creature
 
int mounted_creature_id = 0
 
int activity_vehicle_part_index = -1
 
std::array< int, num_hp_partshealed_total
 
std::map< std::string, int > mutation_category_level
 
std::vector< tripoint_abs_omtomt_path
 Route for overmap scale traveling. More...
 
mutation_collection my_mutations
 Traits / mutations of the character. More...
 
time_point last_sleep_check = calendar::turn_zero
 
bool bio_soporific_powered_at_last_sleep_check = false
 
std::array< int, num_bptemp_cur
 
std::array< int, num_bpfrostbite_timer
 
std::array< int, num_bptemp_conv
 
std::array< int, num_bpbody_wetness
 
std::array< int, num_bpdrench_capacity
 
time_point next_climate_control_check
 
bool last_climate_control_ret = false
 
- Public Attributes inherited from Creature
FacingDirection facing = FD_RIGHT
 return the direction the creature is facing, for sdl horizontal flip More...
 
int moves = 0
 

Static Public Attributes

static const std::vector< material_idfleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
 
- Static Public Attributes inherited from Creature
static const std::map< std::string, m_sizesize_map
 
static const std::set< material_idcmat_flesh
 
static const std::set< material_idcmat_fleshnveg
 
static const std::set< material_idcmat_flammable
 
static const std::set< material_idcmat_flameres
 
static std::vector< int > dispersion_for_even_chance_of_good_hit = default_dispersion_for_ecogh
 

Protected Member Functions

void do_skill_rust ()
 
void apply_mods (const trait_id &mut, bool add_remove)
 Applies stat mods to character. More...
 
char_encumbrance_data calc_encumbrance () const
 Recalculate encumbrance for all body parts. More...
 
char_encumbrance_data calc_encumbrance (const item &new_item) const
 Recalculate encumbrance for all body parts as if new_item was also worn. More...
 
void mut_cbm_encumb (char_encumbrance_data &vals) const
 Applies encumbrance from mutations and bionics only. More...
 
std::list< item >::iterator position_to_wear_new_item (const item &new_item)
 Return the position in the worn list where new_item would be put by default. More...
 
void item_encumb (char_encumbrance_data &vals, const item &new_item) const
 Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items. More...
 
void on_damage_of_type (int adjusted_damage, damage_type type, const bodypart_id &bp) override
 
 Character ()
 
 Character (Character &&)
 
Characteroperator= (Character &&)
 
void store (JsonOut &json) const
 Load variables from json into object. More...
 
void load (const JsonObject &data)
 Gather variables for saving. More...
 
- Protected Member Functions inherited from Creature
void set_killer (Creature *killer)
 
 Creature ()
 
 Creature (const Creature &)=default
 
 Creature (Creature &&)=default
 
Creatureoperator= (const Creature &)=default
 
Creatureoperator= (Creature &&)=default
 
void store (JsonOut &jsout) const
 These two functions are responsible for storing and loading the members of this class to/from json data. More...
 
void load (const JsonObject &jsin)
 

Protected Attributes

std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bpmut_drench
 
tripoint position
 
int str_bonus = 0
 Bonuses to stats, calculated each turn. More...
 
int dex_bonus = 0
 
int per_bonus = 0
 
int int_bonus = 0
 
int healthy = 0
 How healthy the character is. More...
 
int healthy_mod = 0
 
int init_age = 25
 age in years at character creation More...
 
int init_height = 175
 height at character creation More...
 
m_size size_class = MS_MEDIUM
 Size class of character. More...
 
trap_map known_traps
 
pimpl< char_encumbrance_dataencumbrance_cache
 
std::unordered_set< trait_idmy_traits
 Contains mutation ids of the base traits. More...
 
std::vector< const mutation_branch * > cached_mutations
 Pointers to mutation branches in my_mutations. More...
 
pimpl< SkillLevelMap_skills
 Character skills. More...
 
pimpl< SkillLevelMapautolearn_skills_stamp
 Stamp of character skills. More...
 
pimpl< recipe_subsetlearned_recipes
 Subset of learned recipes. More...
 
std::bitset< NUM_VISION_MODESvision_mode_cache
 
float nv_range = 0
 
int sight_max = 0
 
time_point time_died = calendar::before_time_starts
 
pimpl< pathfinding_settingspath_settings
 Cache for pathfinding settings. More...
 
int faction_api_version = 2
 
faction_id fac_id
 
factionmy_fac = nullptr
 
character_movemode move_mode = CMM_WALK
 
std::map< vitamin_id, int > vitamin_levels
 Current deficiency/excess quantity for each vitamin. More...
 
pimpl< player_moralemorale
 
pimpl< enchantmentenchantment_cache
 
std::unordered_map< point_abs_omt, time_durationovermap_time
 Amount of time the player has spent in each overmap tile. More...
 
- Protected Attributes inherited from Creature
Creaturekiller = nullptr
 
pimpl< effects_mapeffects
 
std::unordered_map< std::string, std::string > values
 
int num_blocks = 0
 
int num_dodges = 0
 
int num_blocks_bonus = 0
 
int num_dodges_bonus = 0
 
int armor_bash_bonus = 0
 
int armor_cut_bonus = 0
 
int armor_bullet_bonus = 0
 
int speed_base = 0
 
int speed_bonus = 0
 
float speed_mult = 0.f
 
float dodge_bonus = 0.0
 
int block_bonus = 0
 
float hit_bonus = 0.0
 
bool fake = false
 

Private Member Functions

bool valid_aoe_technique (Creature &t, const ma_technique &technique)
 Check if an area-of-effect technique has valid targets. More...
 
bool valid_aoe_technique (Creature &t, const ma_technique &technique, std::vector< Creature * > &targets)
 
int get_mod (const trait_id &mut, const std::string &arg) const
 Retrieves a stat mod of a mutation. More...
 
void apply_skill_boost ()
 Applies skill-based boosts to stats. More...
 
void old_mutate ()
 
void suffer_water_damage (const mutation_branch &mdata)
 suffer() subcalls More...
 
void suffer_mutation_power (const mutation_branch &mdata, char_trait_data &tdata)
 
void suffer_while_underwater ()
 
void suffer_from_addictions ()
 
void suffer_while_awake (int current_stim)
 
void suffer_from_chemimbalance ()
 
void suffer_from_schizophrenia ()
 
void suffer_from_asthma (int current_stim)
 
void suffer_feral_kill_withdrawl ()
 
void suffer_in_sunlight ()
 
void suffer_from_sunburn ()
 
void suffer_from_other_mutations ()
 
void suffer_from_radiation ()
 
void suffer_from_bad_bionics ()
 
void suffer_from_artifacts ()
 
void suffer_from_stimulants (int current_stim)
 
void suffer_without_sleep (int sleep_deprivation)
 
bool is_visible_in_range (const Creature &critter, int range) const
 Check whether the other creature is in range and can be seen by this creature. More...
 

Private Attributes

player_activity destination_activity
 
character_id id
 
units::energy power_level
 
units::energy max_power_level
 
int stored_calories = 0
 Needs (hunger, starvation, thirst, fatigue, etc.) More...
 
int thirst = 0
 
int stamina = 0
 
int fatigue = 0
 
int sleep_deprivation = 0
 
bool check_encumbrance = true
 
int stim = 0
 
int pkill = 0
 
int radiation = 0
 
std::vector< tripointauto_move_route
 
std::optional< tripointnext_expected_position
 
scenttype_id type_of_scent
 
struct weighted_int_list< std::string > melee_miss_reasons
 
int cached_moves = 0
 
tripoint cached_position
 
inventory cached_crafting_inventory
 
std::array< double, npc_ai_info::num_npc_ai_infonpc_ai_info_cache
 
safe_reference_anchor anchor
 

Additional Inherited Members

Detailed Description

Definition at line 225 of file character.h.

Member Typedef Documentation

◆ trap_map

using Character::trap_map = std::map<tripoint, std::string>

Definition at line 2080 of file character.h.

Member Enumeration Documentation

◆ water_tolerance

Enumerator
WT_IGNORED 
WT_NEUTRAL 
WT_GOOD 
NUM_WATER_TOLERANCE 

Definition at line 789 of file character.h.

789 {
790 WT_IGNORED = 0,
792 WT_GOOD,
794 };
@ WT_NEUTRAL
Definition: character.h:791
@ WT_IGNORED
Definition: character.h:790
@ NUM_WATER_TOLERANCE
Definition: character.h:793

Constructor & Destructor Documentation

◆ Character() [1/3]

Character::Character ( const Character )
delete

◆ ~Character()

Character::~Character ( )
overridedefault

◆ Character() [2/3]

Character::Character ( )
protected

Definition at line 409 of file character.cpp.

409 :
411 damage_bandaged( {{ 0 }} ),
412 damage_disinfected( {{ 0 }} ),
414 id( -1 ),
417{
418 str_max = 0;
419 dex_max = 0;
420 per_max = 0;
421 int_max = 0;
422 str_cur = 0;
423 dex_cur = 0;
424 per_cur = 0;
425 int_cur = 0;
426 str_bonus = 0;
427 dex_bonus = 0;
428 per_bonus = 0;
429 int_bonus = 0;
430 healthy = 0;
431 healthy_mod = 0;
432 thirst = 0;
433 fatigue = 0;
435 set_rad( 0 );
436 tank_plut = 0;
437 reactor_plut = 0;
438 slow_rad = 0;
439 set_stim( 0 );
440 set_stamina( 10000 ); //Temporary value for stamina. It will be reset later from external json option.
441 set_anatomy( anatomy_id("human_anatomy") );
442 set_body();
443 update_type_of_scent( true );
444 pkill = 0;
447 healed_total = { { 0, 0, 0, 0, 0, 0 } };
448
449 name.clear();
450 custom_profession.clear();
452
453 *path_settings = pathfinding_settings{ 0, 1000, 1000, 0, true, true, true, false, true };
454
456 next_expected_position = std::nullopt;
457 temp_cur.fill( BODYTEMP_NORM );
458 frostbite_timer.fill( 0 );
459 temp_conv.fill( BODYTEMP_NORM );
460
461 body_wetness.fill( 0 );
462
475 npc_ai_info_cache.fill(-1.0);
476}
string_id< anatomy > anatomy_id
Definition: anatomy.h:14
@ bp_foot_l
Definition: bodypart.h:52
@ bp_leg_r
Definition: bodypart.h:51
@ bp_eyes
Definition: bodypart.h:44
@ bp_hand_l
Definition: bodypart.h:48
@ bp_arm_l
Definition: bodypart.h:46
@ bp_leg_l
Definition: bodypart.h:50
@ bp_hand_r
Definition: bodypart.h:49
@ bp_head
Definition: bodypart.h:43
@ bp_torso
Definition: bodypart.h:42
@ bp_mouth
Definition: bodypart.h:45
@ bp_foot_r
Definition: bodypart.h:53
@ bp_arm_r
Definition: bodypart.h:47
@ CMM_WALK
Definition: character.h:109
bool last_climate_control_ret
Definition: character.h:2294
character_movemode move_mode
Definition: character.h:2202
int str_max
Definition: character.h:259
std::array< int, num_bp > frostbite_timer
Definition: character.h:2289
void update_type_of_scent(bool init=false)
Definition: character.cpp:8733
int str_cur
Definition: character.h:264
int str_bonus
Bonuses to stats, calculated each turn.
Definition: character.h:2128
profession_id prof
Definition: character.h:573
int dex_cur
Definition: character.h:265
std::array< int, num_bp > temp_conv
Definition: character.h:2289
int max_stored_kcal() const
Definition: character.cpp:4342
int per_max
Definition: character.h:262
void set_stim(int new_stim)
Definition: character.cpp:7065
void set_stamina(int new_stamina)
Definition: character.cpp:7109
std::string name
Definition: character.h:1564
std::array< int, num_bp > body_wetness
Definition: character.h:2290
time_point next_climate_control_check
Definition: character.h:2293
int stored_calories
Needs (hunger, starvation, thirst, fatigue, etc.)
Definition: character.h:2250
int per_bonus
Definition: character.h:2130
time_point cached_time
Definition: character.h:1603
std::string custom_profession
Definition: character.h:574
int dex_bonus
Definition: character.h:2129
std::optional< tripoint > next_expected_position
Definition: character.h:2266
pimpl< pathfinding_settings > path_settings
Cache for pathfinding settings.
Definition: character.h:2191
std::array< int, num_hp_parts > damage_bandaged
Definition: character.h:1568
character_id id
Definition: character.h:2244
int healthy
How healthy the character is.
Definition: character.h:2134
int sleep_deprivation
Definition: character.h:2256
int int_cur
Definition: character.h:266
int int_max
Definition: character.h:261
int reactor_plut
Definition: character.h:1593
int fatigue
Definition: character.h:2255
std::array< int, num_bp > drench_capacity
Definition: character.h:2291
std::array< int, num_bp > temp_cur
Definition: character.h:2289
void initialize_stomach_contents()
Definition: stomach.cpp:195
std::array< int, num_hp_parts > healed_total
Definition: character.h:1777
void set_rad(int new_rad)
Definition: character.cpp:7080
int slow_rad
Definition: character.h:1594
std::array< double, npc_ai_info::num_npc_ai_info > npc_ai_info_cache
Definition: character.h:2275
int per_cur
Definition: character.h:267
int tank_plut
Definition: character.h:1592
int healthy_mod
Definition: character.h:2135
int dex_max
Definition: character.h:260
int thirst
Definition: character.h:2252
int int_bonus
Definition: character.h:2131
std::array< int, num_hp_parts > damage_disinfected
Definition: character.h:1568
void set_body()
Definition: creature.cpp:1574
void set_anatomy(anatomy_id anat)
Definition: creature.cpp:1564
static const profession_id & generic()
Definition: profession.cpp:248
const time_point before_time_starts
A time point that is always before the current turn, even when the game has just started.
Definition: calendar.cpp:25
static constexpr int BODYTEMP_NORM
Level 1 hotness.
Definition: weather.h:36

◆ Character() [3/3]

Character::Character ( Character &&  )
protecteddefault

Member Function Documentation

◆ absorb_hit()

void Character::absorb_hit ( const bodypart_id bp,
damage_instance dam 
)
overridevirtual

Runs through all bionics and armor on a part and reduces damage through their armor_absorb.

Implements Creature.

Definition at line 8030 of file character.cpp.

8031{
8032 std::list<item> worn_remains;
8033 bool armor_destroyed = false;
8034
8035 for( damage_unit &elem : dam.damage_units ) {
8036 if( elem.amount < 0 ) {
8037 // Prevents 0 damage hits (like from hallucinations) from ripping armor
8038 elem.amount = 0;
8039 continue;
8040 }
8041
8042 // The bio_ads CBM absorbs percentage melee damage and ranged damage (where possible) after armour.
8043 if( has_active_bionic( bio_ads ) && ( elem.amount > 0 ) && ( elem.type == DT_BASH ||
8044 elem.type == DT_CUT || elem.type == DT_STAB || elem.type == DT_BULLET ) ) {
8045 float elem_multi = 1;
8047 // HACK: Halves charge rate when hit for the next 3 turns, doesn't stack. See bionics.cpp for more information.
8048 bio.charge_timer = 6;
8049 // Bullet affected significantly more than stab, stab more than cut, cut more than bash.
8050 if( elem.type == DT_BASH ) {
8051 elem_multi = 0.8;
8052 } else if( elem.type == DT_CUT ) {
8053 elem_multi = 0.7;
8054 } else if( elem.type == DT_STAB ) {
8055 elem_multi = 0.55;
8056 } else if( elem.type == DT_BULLET ) {
8057 elem_multi = 0.25;
8058 }
8059 units::energy ads_cost = elem.amount * 500_J;
8060 if( bio.energy_stored >= ads_cost ) {
8061 dam.mult_damage( elem_multi );
8062 bio.energy_stored -= ads_cost;
8063 } else if( bio.energy_stored < ads_cost && bio.energy_stored != 0_kJ ) {
8064 // If you get hit and you lack energy it either deactivates, or deactivates and shorts out.
8065 // Either way you still get protection.
8066 dam.mult_damage( elem_multi );
8067 bio.energy_stored = 0_kJ;
8068 deactivate_bionic( bio );
8069 const units::energy shatter_thresh = ( elem.type == DT_BULLET ) ? 20_kJ : 15_kJ;
8070 if( ads_cost >= shatter_thresh ) {
8071 if( bio.incapacitated_time == 0_turns ) {
8072 add_msg_if_player( m_bad, _( "Your forcefield shatters and the feedback shorts out the %s!" ),
8073 bio.info().name );
8074 }
8075 int over = units::to_kilojoule( ads_cost - ( shatter_thresh - 5_kJ ) );
8076 bio.incapacitated_time += ( ( over / 5 ) ) * 1_turns;
8077 } else {
8078 add_msg_if_player( m_bad, _( "Your forcefield crackles and the %s powers down." ),
8079 bio.info().name );
8080 }
8081 } else {
8082 //You tried to (re)activate it and immediately enter combat, no mitigation for you.
8083 deactivate_bionic( bio );
8084 add_msg_if_player( m_bad, _( "The %s is interrupted and powers down." ), bio.info().name );
8085 }
8086 }
8087
8088 armor_enchantment_adjust( *this, elem );
8089
8090 // Only the outermost armor can be set on fire
8091 bool outermost = true;
8092 // The worn vector has the innermost item first, so
8093 // iterate reverse to damage the outermost (last in worn vector) first.
8094 for( auto iter = worn.rbegin(); iter != worn.rend(); ) {
8095 item &armor = *iter;
8096
8097 if( !armor.covers( bp->token ) ) {
8098 ++iter;
8099 continue;
8100 }
8101
8102 const std::string pre_damage_name = armor.tname();
8103 bool destroy = false;
8104
8105 item_armor_enchantment_adjust( *this, elem, armor );
8106 // Heat damage can set armor on fire
8107 // Even though it doesn't cause direct physical damage to it
8108 if( outermost && elem.type == DT_HEAT && elem.amount >= 1.0f ) {
8109 // TODO: Different fire intensity values based on damage
8110 fire_data frd{ 2 };
8111 destroy = armor.burn( frd );
8112 int fuel = roll_remainder( frd.fuel_produced );
8113 if( fuel > 0 ) {
8114 add_effect( effect_onfire, time_duration::from_turns( fuel + 1 ), bp->token, 0, false, true );
8115 }
8116 }
8117
8118 if( !destroy ) {
8119 destroy = armor_absorb( elem, armor );
8120 }
8121
8122 if( destroy ) {
8123 if( g->u.sees( *this ) ) {
8124 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ),
8125 m_neutral, _( "destroyed" ), m_info );
8126 }
8127 destroyed_armor_msg( *this, pre_damage_name );
8128 armor_destroyed = true;
8129 armor.on_takeoff( *this );
8130 for( const item *it : armor.contents.all_items_top() ) {
8131 worn_remains.push_back( *it );
8132 }
8133 // decltype is the type name of the iterator, note that reverse_iterator::base returns the
8134 // iterator to the next element, not the one the revers_iterator points to.
8135 // http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
8136 iter = decltype( iter )( worn.erase( --( iter.base() ) ) );
8137 } else {
8138 ++iter;
8139 outermost = false;
8140 }
8141 }
8142
8143 passive_absorb_hit( bp, elem );
8144
8145 if( elem.type == DT_BASH ) {
8146 if( has_trait( trait_LIGHT_BONES ) ) {
8147 elem.amount *= 1.4;
8148 }
8149 if( has_trait( trait_HOLLOW_BONES ) ) {
8150 elem.amount *= 1.8;
8151 }
8152 }
8153
8154 elem.amount = std::max( elem.amount, 0.0f );
8155 }
8156 map &here = get_map();
8157 for( item &remain : worn_remains ) {
8158 here.add_item_or_charges( pos(), remain );
8159 }
8160 if( armor_destroyed ) {
8162 }
8163}
static const trait_id trait_HOLLOW_BONES("HOLLOW_BONES")
static void destroyed_armor_msg(Character &who, const std::string &pre_damage_name)
Definition: character.cpp:7940
static const bionic_id bio_ads("bio_ads")
static void item_armor_enchantment_adjust(const Character &guy, damage_unit &du, const item &armor)
Definition: character.cpp:7954
static const trait_id trait_LIGHT_BONES("LIGHT_BONES")
static void armor_enchantment_adjust(const Character &guy, damage_unit &du)
Definition: character.cpp:7994
static const efftype_id effect_onfire("onfire")
bionic & get_bionic_state(const bionic_id &id)
Get state of bionic with given id.
Definition: character.cpp:1804
int posx() const override
Definition: character.h:795
int posy() const override
Definition: character.h:798
std::list< item > worn
Definition: character.h:1567
bool armor_absorb(damage_unit &du, item &armor)
Reduces and mutates du, prints messages about armor taking damage.
Definition: character.cpp:8165
void drop_invalid_inventory()
Definition: character.cpp:3191
void passive_absorb_hit(const bodypart_id &bp, damage_unit &du) const
Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.
Definition: character.cpp:7921
const tripoint & pos() const override
Definition: character.cpp:601
bool deactivate_bionic(bionic &bio, bool eff_only=false)
Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.
Definition: bionics.cpp:1107
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:101
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1825
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:1008
virtual void add_msg_if_player(const std::string &) const
Definition: creature.h:605
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
Definition: item.h:210
item_contents contents
Definition: item.h:2171
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4576
void on_takeoff(Character &p)
Callback when a character takes off an item.
Definition: item.cpp:4417
bool burn(fire_data &frd)
Burns the item.
Definition: item.cpp:8285
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:748
Manage and cache data about a part of the map.
Definition: map.h:384
void add(point pos, direction p_oDir, const std::string &p_sText, game_message_type p_gmt, const std::string &p_sText2="", game_message_type p_gmt2=m_neutral, const std::string &p_sType="")
Definition: output.cpp:1757
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_STAB
Definition: damage.h:27
@ DT_BASH
Definition: damage.h:24
@ DT_CUT
Definition: damage.h:25
@ DT_BULLET
Definition: damage.h:31
@ DT_HEAT
Definition: damage.h:28
@ m_neutral
Definition: enums.h:267
@ m_info
Definition: enums.h:265
@ m_bad
Definition: enums.h:261
std::unique_ptr< game > g
Definition: game.cpp:285
map & get_map()
Definition: map.cpp:148
auto here(const Character &you) -> elevator::tiles
constexpr value_type to_kilojoule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:46
std::string remove_color_tags(const std::string &s)
Removes the color tags from the input string.
Definition: output.cpp:145
scrollingcombattext SCT
Definition: output.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96
translation name
Definition: bionics.h:34
const bionic_data & info() const
Definition: bionics.h:174
int charge_timer
Definition: bionics.h:157
units::energy energy_stored
Definition: bionics.h:167
time_duration incapacitated_time
Definition: bionics.h:165
std::vector< damage_unit > damage_units
Definition: damage.h:52
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
damage_type type
Definition: damage.h:36
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
Definition: point.h:35
#define _(msg)
Definition: translations.h:116

References _, scrollingcombattext::add(), Creature::add_effect(), Creature::add_msg_if_player(), item_contents::all_items_top(), damage_unit::amount, armor_absorb(), armor_enchantment_adjust(), bio_ads, item::burn(), bionic::charge_timer, item::contents, item::covers(), damage_instance::damage_units, deactivate_bionic(), destroyed_armor_msg(), drop_invalid_inventory(), DT_BASH, DT_BULLET, DT_CUT, DT_HEAT, DT_STAB, effect_onfire, bionic::energy_stored, time_duration::from_turns(), g, get_bionic_state(), get_map(), has_active_bionic(), has_trait(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), bionic::incapacitated_time, bionic::info(), item_armor_enchantment_adjust(), m_bad, m_info, m_neutral, damage_instance::mult_damage(), bionic_data::name, NORTH, item::on_takeoff(), passive_absorb_hit(), pos(), posx(), posy(), remove_color_tags(), roll_remainder(), SCT, item::tname(), units::to_kilojoule(), trait_HOLLOW_BONES, trait_LIGHT_BONES, damage_unit::type, and worn.

◆ action_taken()

void Character::action_taken ( )

Called after every action, invalidates player caches.

Definition at line 812 of file character.cpp.

813{
814 nv_cached = false;
815}
bool nv_cached
Definition: character.h:1569

References nv_cached.

Referenced by game::do_turn().

◆ activate_bionic()

bool Character::activate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic activation effects of the entered bionic, returns if anything activated.

Definition at line 588 of file bionics.cpp.

589{
590 const bool mounted = is_mounted();
591 if( bio.incapacitated_time > 0_turns ) {
592 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be activated." ),
593 bio.info().name );
594 return false;
595 }
596
597 // eff_only means only do the effect without messing with stats or displaying messages
598 if( !eff_only ) {
599 if( bio.powered ) {
600 // It's already on!
601 return false;
602 }
603 if( !enough_power_for( bio.id ) ) {
604 add_msg_if_player( m_info, _( "You don't have the power to activate your %s." ),
605 bio.info().name );
606 return false;
607 }
608
609 // HACK: burn_fuel() doesn't check for available fuel in remote source on start.
610 // If CBM is successfully activated, the check will occur when it actually tries to draw power
611 if( !bio.info().is_remote_fueled ) {
612 if( !burn_fuel( bio, true ) ) {
613 return false;
614 }
615 }
616
617 // We can actually activate now, do activation-y things
619
620 bio.powered = bio.info().has_flag( flag_BIONIC_TOGGLED ) || bio.info().charge_time > 0;
621
622 if( bio.info().charge_time > 0 ) {
623 bio.charge_timer = bio.info().charge_time;
624 }
625 if( !bio.id->enchantments.empty() ) {
627 }
628 }
629
630 auto add_msg_activate = [&]() {
631 if( !eff_only && !bio.is_auto_start_keep_full() ) {
632 add_msg_if_player( m_info, _( "You activate your %s." ), bio.info().name );
633 } else if( get_player_character().sees( pos() ) ) {
634 add_msg( m_info, _( "%s activates their %s." ), disp_name(),
635 bio.info().name );
636 }
637 };
638 auto refund_power = [&]() {
639 if( !eff_only ) {
641 }
642 };
643
644 item tmp_item;
645 const w_point &weatherPoint = get_weather().get_precise();
646
647 map &here = get_map();
648 // On activation effects go here
649 if( bio.info().has_flag( flag_BIONIC_GUN ) ) {
650 add_msg_activate();
651 refund_power(); // Power usage calculated later, in avatar_action::fire
653 bio.info().power_activate );
654 } else if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
656 add_msg_if_player( m_info, _( "Deactivate your %s first!" ), primary_weapon().tname() );
657 refund_power();
658 bio.powered = false;
659 return false;
660 }
661
662 if( !primary_weapon().is_null() ) {
663 const std::string query = string_format( _( "Stop wielding %s?" ), primary_weapon().tname() );
664 if( !dispose_item( item_location( *this, &primary_weapon() ), query ) ) {
665 refund_power();
666 bio.powered = false;
667 return false;
668 }
669 }
670
671 add_msg_activate();
673 primary_weapon().invlet = '#';
674 if( is_player() && bio.ammo_count > 0 ) {
677 }
679 } else if( bio.id == bio_ears && has_active_bionic( bio_earplugs ) ) {
680 add_msg_activate();
681 for( bionic &bio : *my_bionics ) {
682 if( bio.id == bio_earplugs ) {
683 bio.powered = false;
684 add_msg_if_player( m_info, _( "Your %s automatically turn off." ),
685 bio.info().name );
686 }
687 }
688 } else if( bio.id == bio_earplugs && has_active_bionic( bio_ears ) ) {
689 add_msg_activate();
690 for( bionic &bio : *my_bionics ) {
691 if( bio.id == bio_ears ) {
692 bio.powered = false;
693 add_msg_if_player( m_info, _( "Your %s automatically turns off." ),
694 bio.info().name );
695 }
696 }
697 } else if( bio.id == bio_evap ) {
698 add_msg_activate();
699 const w_point &weatherPoint = get_weather().get_precise();
700 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
701 g->is_sheltered( g->u.pos() ) );
702 // thirst units = 5 mL
703 int water_available = std::lround( humidity * 3.0 / 100.0 );
704 if( water_available == 0 ) {
705 bio.powered = false;
706 add_msg_if_player( m_bad, _( "There is not enough humidity in the air for your %s to function." ),
707 bio.info().name );
708 return false;
709 } else if( water_available == 1 ) {
711 _( "Your %s issues a low humidity warning. Efficiency will be reduced." ),
712 bio.info().name );
713 }
714 } else if( bio.id == bio_tools ) {
715 add_msg_activate();
717 } else if( bio.id == bio_cqb ) {
718 add_msg_activate();
719 const avatar *you = as_avatar();
720 if( you && !martial_arts_data->pick_style( *you ) ) {
721 bio.powered = false;
722 add_msg_if_player( m_info, _( "You change your mind and turn it off." ) );
723 return false;
724 }
725 } else if( bio.id == bio_resonator ) {
726 add_msg_activate();
727 //~Sound of a bionic sonic-resonator shaking the area
728 sounds::sound( pos(), 30, sounds::sound_t::combat, _( "VRRRRMP!" ), false, "bionic",
729 static_cast<std::string>( bio_resonator ) );
730 for( const tripoint &bashpoint : here.points_in_radius( pos(), 1 ) ) {
731 here.bash( bashpoint, 110 );
732 // Multibash effect, so that doors &c will fall
733 here.bash( bashpoint, 110 );
734 here.bash( bashpoint, 110 );
735 }
736
737 mod_moves( -100 );
738 } else if( bio.id == bio_time_freeze ) {
739 if( mounted ) {
740 refund_power();
741 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
742 return false;
743 }
744 add_msg_activate();
745
747 set_power_level( 0_kJ );
748 add_msg_if_player( m_good, _( "Your speed suddenly increases!" ) );
749 if( one_in( 3 ) ) {
750 add_msg_if_player( m_bad, _( "Your muscles tear with the strain." ) );
751 apply_damage( nullptr, bodypart_id( "arm_l" ), rng( 5, 10 ) );
752 apply_damage( nullptr, bodypart_id( "arm_r" ), rng( 5, 10 ) );
753 apply_damage( nullptr, bodypart_id( "leg_l" ), rng( 7, 12 ) );
754 apply_damage( nullptr, bodypart_id( "leg_r" ), rng( 7, 12 ) );
755 apply_damage( nullptr, bodypart_id( "torso" ), rng( 5, 15 ) );
756 }
757 if( one_in( 5 ) ) {
758 add_effect( effect_teleglow, rng( 5_minutes, 40_minutes ) );
759 }
760 } else if( bio.id == bio_teleport ) {
761 if( mounted ) {
762 refund_power();
763 add_msg_if_player( m_info, _( "You cannot activate %s while mounted." ), bio.info().name );
764 return false;
765 }
766 add_msg_activate();
767
768 teleport::teleport( *this );
769 add_effect( effect_teleglow, 30_minutes );
770 mod_moves( -100 );
771 } else if( bio.id == bio_blood_anal ) {
772 add_msg_activate();
774 } else if( bio.id == bio_blood_filter ) {
775 add_msg_activate();
776 static const std::vector<efftype_id> removable = {{
784 }
785 };
786
787 for( const auto &eff : removable ) {
788 remove_effect( eff );
789 }
790 // Purging the substance won't remove the fatigue it caused
793 set_painkiller( 0 );
794 set_stim( 0 );
795 mod_moves( -100 );
796 } else if( bio.id == bio_torsionratchet ) {
797 add_msg_activate();
798 add_msg_if_player( m_info, _( "Your torsion ratchet locks onto your joints." ) );
799 } else if( bio.id == bio_jointservo ) {
800 add_msg_activate();
801 add_msg_if_player( m_info, _( "You can now run faster, assisted by joint servomotors." ) );
802 } else if( bio.id == bio_lighter ) {
803 const std::optional<tripoint> pnt = choose_adjacent( _( "Start a fire where?" ) );
804 if( pnt && here.is_flammable( *pnt ) ) {
805 add_msg_activate();
806 here.add_field( *pnt, fd_fire, 1 );
807 mod_moves( -100 );
808 } else {
809 refund_power();
810 add_msg_if_player( m_info, _( "There's nothing to light there." ) );
811 return false;
812 }
813 } else if( bio.id == bio_geiger ) {
814 add_msg_activate();
815 add_msg_if_player( m_info, _( "Your radiation level: %d" ), get_rad() );
816 } else if( bio.id == bio_adrenaline ) {
817 add_msg_activate();
819 add_msg_if_player( m_bad, _( "Safeguards kick in, and the bionic refuses to activate!" ) );
820 refund_power();
821 return false;
822 } else {
823 add_msg_activate();
824 add_effect( effect_adrenaline, 20_minutes );
825 }
826 } else if( bio.id == bio_emp ) {
827 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Create an EMP where?" ) ) ) {
828 add_msg_activate();
830 mod_moves( -100 );
831 } else {
832 refund_power();
833 return false;
834 }
835 } else if( bio.id == bio_hydraulics ) {
836 add_msg_activate();
837 add_msg_if_player( m_good, _( "Your muscles hiss as hydraulic strength fills them!" ) );
838 //~ Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
839 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
840 static_cast<std::string>( bio_hydraulics ) );
841 } else if( bio.id == bio_water_extractor ) {
842 bool no_target = true;
843 bool extracted = false;
844 for( item &it : here.i_at( pos() ) ) {
845 static const auto volume_per_water_charge = 500_ml;
846 if( it.is_corpse() ) {
847 const int avail = it.get_var( "remaining_water", it.volume() / volume_per_water_charge );
848 if( avail > 0 ) {
849 no_target = false;
850 if( query_yn( _( "Extract water from the %s" ),
851 colorize( it.tname(), it.color_in_inventory() ) ) ) {
852 item water( itype_water_clean, calendar::turn, avail );
853 if( liquid_handler::consume_liquid( water ) ) {
854 add_msg_activate();
855 extracted = true;
856 it.set_var( "remaining_water", static_cast<int>( water.charges ) );
857 }
858 break;
859 }
860 }
861 }
862 }
863 if( no_target ) {
864 add_msg_if_player( m_bad, _( "There is no suitable corpse on this tile." ) );
865 }
866 if( !extracted ) {
867 refund_power();
868 return false;
869 }
870 } else if( bio.id == bio_magnet ) {
871 add_msg_activate();
872 static const std::set<material_id> affected_materials =
873 { material_id( "iron" ), material_id( "steel" ) };
874 // Remember all items that will be affected, then affect them
875 // Don't "snowball" by affecting some items multiple times
876 std::vector<std::pair<item, tripoint>> affected;
877 const units::mass weight_cap = weight_capacity();
878 for( const tripoint &p : here.points_in_radius( pos(), 10 ) ) {
879 if( p == pos() || !here.has_items( p ) || here.has_flag( flag_SEALED, p ) ) {
880 continue;
881 }
882
883 map_stack stack = here.i_at( p );
884 for( auto it = stack.begin(); it != stack.end(); it++ ) {
885 if( it->weight() < weight_cap &&
886 it->made_of_any( affected_materials ) ) {
887 affected.emplace_back( std::make_pair( *it, p ) );
888 stack.erase( it );
889 break;
890 }
891 }
892 }
893
894 for( const std::pair<item, tripoint> &pr : affected ) {
895 projectile proj;
896 proj.speed = 50;
897 proj.impact = damage_instance::physical( pr.first.weight() / 250_gram, 0, 0, 0 );
898 // make the projectile stop one tile short to prevent hitting the player
899 proj.range = rl_dist( pr.second, pos() ) - 1;
900 static const std::set<ammo_effect_str_id> ammo_effects = {{
901 ammo_effect_str_id( "NO_ITEM_DAMAGE" ),
902 ammo_effect_str_id( "DRAW_AS_LINE" ),
903 ammo_effect_str_id( "NO_DAMAGE_SCALING" ),
904 ammo_effect_str_id( "JET" ),
905 }
906 };
907 for( const auto &eff : ammo_effects ) {
908 proj.add_effect( eff );
909 }
910
912 proj, pr.second, pos(), dispersion_sources{ 0 }, this );
913 here.add_item_or_charges( dealt.end_point, pr.first );
914 }
915
916 mod_moves( -100 );
917 } else if( bio.id == bio_lockpick ) {
918 bool used = false;
919 bool tried_lockpick = false;
920 const std::optional<tripoint> pnt = choose_adjacent( _( "Use your lockpick where?" ) );
921 std::string open_message;
922 if( pnt ) {
923 tried_lockpick = true;
924 ter_id ter_type = g->m.ter( *pnt );
925 furn_id furn_type = g->m.furn( *pnt );
926 lockpicking_open_result lr = get_lockpicking_open_result( ter_type, furn_type );
927 ter_id new_ter_type = lr.new_ter_type;
928 furn_id new_furn_type = lr.new_furn_type;
929 open_message = lr.open_message;
930
931 if( new_ter_type != t_null || new_furn_type != f_null ) {
932 g->m.has_furn( *pnt ) ?
933 g->m.furn_set( *pnt, new_furn_type ) :
934 static_cast<void>( g->m.ter_set( *pnt, new_ter_type ) );
935 used = true;
936 }
937 }
938
939 if( used ) {
940 add_msg_activate();
941 add_msg_if_player( m_good, open_message );
942 mod_moves( -100 );
943 } else {
944 refund_power();
945 if( tried_lockpick ) {
946 add_msg_if_player( m_info, _( "There is nothing to lockpick nearby." ) );
947 }
948 return false;
949 }
950 } else if( bio.id == bio_flashbang ) {
951 add_msg_activate();
952 explosion_handler::flashbang( pos(), true, "explosion" );
953 mod_moves( -100 );
954 } else if( bio.id == bio_shockwave ) {
955 add_msg_activate();
956
958 sw.affects_player = false;
959 sw.radius = 3;
960 sw.force = 4;
961 sw.stun = 2;
962 sw.dam_mult = 8;
963 // affects_player is always false, so assuming the player is always the source of this
964 explosion_handler::shockwave( pos(), sw, "explosion", &get_player_character() );
965 add_msg_if_player( m_neutral, _( "You unleash a powerful shockwave!" ) );
966 mod_moves( -100 );
967 } else if( bio.id == bio_meteorologist ) {
969 add_msg_activate();
970 // Calculate local wind power
971 int vehwindspeed = 0;
972 if( optional_vpart_position vp = here.veh_at( pos() ) ) {
973 // vehicle velocity in mph
974 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
975 }
976 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
977 /* cache g->get_temperature( player location ) since it is used twice. No reason to recalc */
978 const auto player_local_temp = weather.get_temperature( g->u.pos() );
979 /* windpower defined in internal velocity units (=.01 mph) */
980 double windpower = 100.0f * get_local_windpower( weather.windspeed + vehwindspeed,
981 cur_om_ter, pos(), weather.winddirection, g->is_sheltered( pos() ) );
982 add_msg_if_player( m_info, _( "Temperature: %s." ), print_temperature( player_local_temp ) );
983 add_msg_if_player( m_info, _( "Relative Humidity: %s." ),
985 get_local_humidity( weatherPoint.humidity, weather.weather_id,
986 g->is_sheltered( g->u.pos() ) ) ) );
987 add_msg_if_player( m_info, _( "Pressure: %s." ),
988 print_pressure( static_cast<int>( weatherPoint.pressure ) ) );
989 add_msg_if_player( m_info, _( "Wind Speed: %.1f %s." ),
990 convert_velocity( static_cast<int>( windpower ), VU_WIND ),
992 add_msg_if_player( m_info, _( "Feels Like: %s." ),
995 weatherPoint.humidity,
996 windpower / 100 ) + player_local_temp ) );
997 std::string dirstring = get_dirstring( weather.winddirection );
998 add_msg_if_player( m_info, _( "Wind Direction: From the %s." ), dirstring );
999 } else if( bio.id == bio_remote ) {
1000 add_msg_activate();
1001 int choice = uilist( _( "Perform which function:" ), {
1002 _( "Control vehicle" ), _( "RC radio" )
1003 } );
1004 if( choice >= 0 && choice <= 1 ) {
1005 item ctr;
1006 if( choice == 0 ) {
1007 ctr = item( "remotevehcontrol", calendar::start_of_cataclysm );
1008 } else {
1009 ctr = item( "radiocontrol", calendar::start_of_cataclysm );
1010 }
1012 int power_use = invoke_item( &ctr );
1013 mod_power_level( units::from_kilojoule( -power_use ) );
1014 bio.powered = ctr.active;
1015 } else {
1016 bio.powered = g->remoteveh() != nullptr || !get_value( "remote_controlling" ).empty();
1017 }
1018 } else if( bio.info().is_remote_fueled ) {
1019 std::vector<item *> cables = items_with( []( const item & it ) {
1020 return it.has_flag( flag_CABLE_SPOOL );
1021 } );
1022 bool has_cable = !cables.empty();
1023 bool free_cable = false;
1024 bool success = false;
1025 if( !has_cable ) {
1027 _( "You need a jumper cable connected to a power source to drain power from it." ) );
1028 } else {
1029 for( item *cable : cables ) {
1030 const std::string state = cable->get_var( "state" );
1031 if( state == "cable_charger" ) {
1033 _( "Cable is plugged-in to the CBM but it has to be also connected to the power source." ) );
1034 }
1035 if( state == "cable_charger_link" ) {
1036 add_msg_activate();
1037 success = true;
1039 _( "You are plugged to the vehicle. It will charge you if it has some juice in it." ) );
1040 }
1041 if( state == "solar_pack_link" ) {
1042 add_msg_activate();
1043 success = true;
1045 _( "You are plugged to a solar pack. It will charge you if it's unfolded and in sunlight." ) );
1046 }
1047 if( state == "UPS_link" ) {
1048 add_msg_activate();
1049 success = true;
1051 _( "You are plugged to a UPS. It will charge you if it has some juice in it." ) );
1052 }
1053 if( state == "solar_pack" || state == "UPS" ) {
1055 _( "You have a cable plugged to a portable power source, but you need to plug it in to the CBM." ) );
1056 }
1057 if( state == "pay_out_cable" ) {
1059 _( "You have a cable plugged to a vehicle, but you need to plug it in to the CBM." ) );
1060 }
1061 if( state == "attach_first" ) {
1062 free_cable = true;
1063 }
1064 }
1065
1066 if( free_cable ) {
1068 _( "You have at least one free cable in your inventory that you could use to plug yourself in." ) );
1069 }
1070 }
1071 if( !success ) {
1072 refund_power();
1073 bio.powered = false;
1074 return false;
1075 }
1076
1077 } else if( bio.id == bio_probability_travel ) {
1078 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Tunnel in which direction?" ) ) ) {
1079 if( g->m.impassable( *pnt ) ) {
1080 add_msg_activate();
1081 g->phasing_move( *pnt );
1082 } else {
1083 refund_power();
1084 add_msg_if_player( m_info, _( "There's nothing to phase through there." ) );
1085 return false;
1086 }
1087 } else {
1088 refund_power();
1089 return false;
1090 }
1091 } else {
1092 add_msg_activate();
1093 }
1094
1095 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1097 reset();
1098
1099 // Also reset crafting inventory cache if this bionic spawned a fake item
1100 if( !bio.info().fake_item.is_empty() ) {
1102 }
1103
1104 return true;
1105}
std::optional< tripoint > choose_adjacent(const std::string &message, const bool allow_vertical)
Request player input of adjacent tile, possibly including vertical tiles.
Definition: action.cpp:988
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
dealt_projectile_attack projectile_attack(const projectile &proj_arg, const tripoint &source, const tripoint &target_arg, const dispersion_sources &dispersion, Creature *origin, const vehicle *in_veh)
Fires a projectile at the target point from the source point with total_dispersion dispersion.
Definition: ballistics.cpp:201
static const flag_str_id flag_BIONIC_WEAPON("BIONIC_WEAPON")
static const bionic_id bio_cqb("bio_cqb")
static const bionic_id bio_geiger("bio_geiger")
static const itype_id itype_water_clean("water_clean")
static const efftype_id effect_bloodworms("bloodworms")
static const flag_str_id flag_BIONIC_GUN("BIONIC_GUN")
static const efftype_id effect_weed_high("weed_high")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill_l("pkill_l")
static const efftype_id effect_took_prozac("took_prozac")
static const efftype_id effect_datura("datura")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_badpoison("badpoison")
static const efftype_id effect_dermatik("dermatik")
static const std::string flag_NO_UNWIELD("NO_UNWIELD")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_adrenaline("adrenaline")
static void force_comedown(effect &eff)
Definition: bionics.cpp:447
static const bionic_id bio_evap("bio_evap")
static const efftype_id effect_took_flumed("took_flumed")
static const efftype_id effect_hallu("hallu")
static const efftype_id effect_pblue("pblue")
static const bionic_id bio_water_extractor("bio_water_extractor")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_cocaine_high("cocaine_high")
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_magnet("bio_magnet")
static const efftype_id effect_meth("meth")
static const bionic_id bio_flashbang("bio_flashbang")
static const bionic_id bio_time_freeze("bio_time_freeze")
static const bionic_id bio_meteorologist("bio_meteorologist")
static const std::string flag_CABLE_SPOOL("CABLE_SPOOL")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_shockwave("bio_shockwave")
static const bionic_id bio_emp("bio_emp")
static const bionic_id bio_remote("bio_remote")
static const efftype_id effect_stung("stung")
static const std::string flag_SEALED("SEALED")
static const flag_str_id flag_BIONIC_TOGGLED("BIONIC_TOGGLED")
static const efftype_id effect_cig("cig")
static const bionic_id bio_tools("bio_tools")
static const bionic_id bio_earplugs("bio_earplugs")
static const bionic_id bio_adrenaline("bio_adrenaline")
static const bionic_id bio_lockpick("bio_lockpick")
static const bionic_id bio_blood_anal("bio_blood_anal")
static const bionic_id bio_probability_travel("bio_probability_travel")
static const bionic_id bio_teleport("bio_teleport")
static const efftype_id effect_poison("poison")
static const bionic_id bio_resonator("bio_resonator")
static const bionic_id bio_blood_filter("bio_blood_filter")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_took_xanax("took_xanax")
static const efftype_id effect_pkill3("pkill3")
static const efftype_id effect_took_prozac_bad("took_prozac_bad")
static const bionic_id bio_torsionratchet("bio_torsionratchet")
static const efftype_id effect_iodine("iodine")
static const bionic_id bio_jointservo("bio_jointservo")
int_id< body_part_type > bodypart_id
Definition: bodypart.h:25
Character & get_player_character()
Definition: character.cpp:402
@ ideal_weapon_value
Definition: character.h:101
units::mass weight_capacity() const override
Definition: character.cpp:2627
void conduct_blood_analysis() const
Definition: character.cpp:1962
void mod_power_level(const units::energy &npower)
Definition: character.cpp:1925
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Returns either "you" or the player's name.
Definition: character.cpp:580
pimpl< character_martial_arts > martial_arts_data
Definition: character.h:1586
bool query_yn(const char *const msg, Args &&... args) const
It is supposed to hide the query_yn to simplify player vs.
Definition: character.h:1495
pimpl< bionic_collection > my_bionics
Definition: character.h:1585
virtual bool invoke_item(item *, const tripoint &pt)
Asks how to use the item (if it has more than one use_method) and uses it.
Definition: character.cpp:7231
bool burn_fuel(bionic &bio, bool start=false)
Convert fuel to bionic power.
Definition: bionics.cpp:1195
void set_power_level(const units::energy &npower)
Definition: character.cpp:1915
void set_painkiller(int npkill)
Sets intensity of painkillers
Definition: character.cpp:9798
bool is_mounted() const
Definition: character.cpp:1082
void clear_npc_ai_info_cache(npc_ai_info key) const
void apply_damage(Creature *source, bodypart_id hurt, int dam, bool bypass_med=false) override
Actually hurt the player, hurts a body_part directly, no armor reduction.
Definition: character.cpp:8409
bool enough_power_for(const bionic_id &bid) const
Definition: character.cpp:1957
void set_primary_weapon(const item &new_weapon)
Use this when primary weapon might not exist yet.
Definition: melee.cpp:172
item & primary_weapon()
Legacy code hack, don't use.
Definition: melee.cpp:167
void recalculate_enchantment_cache()
Definition: character.cpp:7863
int get_rad() const
Definition: character.cpp:7075
bool sees(const tripoint &t, bool is_player=false, int range_mod=0) const override
virtual bool dispose_item(item_location &&obj, const std::string &prompt=std::string())
Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.
Definition: character.cpp:7270
void reset() override
Handles stat and bonus reset.
Definition: character.cpp:3646
void reset_encumbrance()
Recalculates encumbrance cache.
Definition: character.cpp:3667
units::energy get_power_level() const
Definition: character.cpp:1905
tripoint_abs_omt global_omt_location() const
Returns the location of the player in global overmap terrain coordinates.
Definition: character.cpp:6275
void invalidate_crafting_inventory()
Definition: crafting.cpp:599
virtual bool is_player() const
Definition: creature.h:92
std::string get_value(const std::string &key) const
Definition: creature.cpp:1382
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1207
bool remove_effect(const efftype_id &eff_id, body_part bp=num_bp)
Removes a listed effect.
Definition: creature.cpp:1164
void mod_moves(int nmoves)
Definition: creature.cpp:1449
const effect & get_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Return the effect that matches the given arguments exactly.
Definition: creature.cpp:1247
virtual bool has_flag(const m_flag) const
Definition: creature.h:491
virtual avatar * as_avatar()
Definition: creature.h:128
Definition: avatar.h:55
A lightweight handle to an item independent of it's location Unlike a raw pointer can be (de-)seriali...
Definition: item_location.h:23
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
bool active
Definition: item.h:2247
item & ammo_set(const itype_id &ammo, int qty=-1)
Filter setting the ammo for this instance Any existing ammo is removed.
Definition: item.cpp:595
int charges
Definition: item.h:2209
bool has_flag(const std::string &flag) const
Definition: item.cpp:5330
char invlet
Definition: item.h:2246
Definition: map.h:105
iterator erase(const_iterator it) override
Definition: map.cpp:154
Simple wrapper to forward functions that may return a std::optional to vpart_position.
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
bool is_empty() const
Returns whether this id is empty.
Definition: string_id.h:306
uilist: scrolling vertical list menu
Definition: ui.h:187
std::vector< item * > items_with(const std::function< bool(const item &)> &filter)
Returns all items (including those within a container) matching the filter.
Definition: visitable.cpp:325
const w_point & get_precise() const
Definition: weather.h:218
std::string colorize(const std::string &text, const nc_color &color)
Definition: color.cpp:669
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
@ m_good
Definition: enums.h:260
@ m_mixed
Definition: enums.h:262
field_type_id fd_fire
Definition: field_type.cpp:345
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:941
int get_local_humidity(double humidity, const weather_type_id &weather, bool sheltered)
Definition: weather.cpp:927
std::string print_temperature(double fahrenheit, int decimals)
Print temperature (and convert to Celsius if Celsius display is enabled.)
Definition: weather.cpp:720
std::string get_dirstring(int angle)
Definition: weather.cpp:877
weather_manager & get_weather()
Definition: weather.cpp:64
std::string print_pressure(double pressure, int decimals)
Print pressure (no conversions.)
Definition: weather.cpp:755
std::string print_humidity(double humidity, int decimals)
Print relative humidity (no conversions.)
Definition: weather.cpp:746
int get_local_windchill(double temperature_f, double humidity, double wind_mph)
Definition: weather.cpp:800
string_id< ammo_effect > ammo_effect_str_id
Definition: map.cpp:105
lockpicking_open_result get_lockpicking_open_result(ter_id ter_type, furn_id furn_type)
Gets lockpicked object and message.
Definition: mapdata.cpp:1063
ter_id t_null
Definition: mapdata.cpp:626
furn_id f_null
Definition: mapdata.cpp:1098
void add_msg(std::string msg)
Definition: messages.cpp:910
void fire_wielded_weapon(avatar &you)
Checks if the wielded weapon is a gun and can be fired then starts interactive aiming.
void fire_ranged_bionic(avatar &you, const item &fake_gun, const units::energy &cost_per_shot)
Stores fake gun specified by the bionic and starts interactive aiming.
@ success
Definition: behavior.h:20
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
time_point turn
Definition: calendar.cpp:36
void shockwave(const tripoint &p, const shockwave_data &sw, const std::string &exp_name, Creature *source)
Shockwave applies knockback with given parameters to all targets within radius of p.
Definition: explosion.cpp:1613
void flashbang(const tripoint &p, bool player_immune, const std::string &exp_name)
Triggers a flashbang explosion at p.
Definition: explosion.cpp:1553
void emp_blast(const tripoint &p)
Triggers an EMP blast at p.
Definition: explosion.cpp:1672
bool consume_liquid(item &liquid, const int radius)
Consume / handle as much of the liquid as possible in varying ways.
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:178
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
constexpr value_type to_fahrenheit(const quantity< value_type, temperature_in_millidegree_celsius_tag > &v)
constexpr quantity< value_type, energy_in_joule_tag > from_kilojoule(const value_type v)
Definition: units_energy.h:32
overmapbuffer overmap_buffer
bool one_in(int chance)
Definition: rng.cpp:65
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
std::vector< enchantment_id > enchantments
bionic enchantments
Definition: bionics.h:113
itype_id fake_item
Fake item created for crafting with this bionic available.
Definition: bionics.h:105
units::energy power_activate
Power cost on activation.
Definition: bionics.h:37
int charge_time
How often a bionic draws or produces power while active in turns.
Definition: bionics.h:47
bool is_remote_fueled
This bionic draws power through a cable.
Definition: bionics.h:65
bool has_flag(const flag_str_id &flag) const
Definition: bionics.cpp:244
itype_id ammo_loaded
Definition: bionics.h:161
bool is_auto_start_keep_full() const
Definition: bionics.cpp:2811
bionic_id id
Definition: bionics.h:156
unsigned int ammo_count
Definition: bionics.h:163
bool powered
Definition: bionics.h:159
static damage_instance physical(float bash, float cut, float stab, float arpen=0.0f)
Definition: damage.cpp:27
std::string open_message
Definition: mapdata.h:166
void add_effect(const ammo_effect_str_id &id)
Definition: projectile.h:58
damage_instance impact
Definition: projectile.h:21
bool affects_player
Definition: explosion.h:30
units::temperature temperature
Definition: weather_gen.h:16
double humidity
Definition: weather_gen.h:17
double pressure
Definition: weather_gen.h:18
string_id< material_type > material_id
Definition: type_id.h:95
double convert_velocity(int velocity, const units_type vel_units)
Convert internal velocity units to units defined by user.
const char * velocity_units(const units_type vel_units)
Create a units label for a velocity value.
@ VU_WIND
Definition: units_utility.h:15

References _, item::active, sounds::activity, projectile::add_effect(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), shockwave_data::affects_player, bionic::ammo_count, bionic::ammo_loaded, item::ammo_set(), apply_damage(), Creature::as_avatar(), item_stack::begin(), bio_adrenaline, bio_blood_anal, bio_blood_filter, bio_cqb, bio_earplugs, bio_ears, bio_emp, bio_evap, bio_flashbang, bio_geiger, bio_hydraulics, bio_jointservo, bio_lighter, bio_lockpick, bio_magnet, bio_meteorologist, bio_probability_travel, bio_remote, bio_resonator, bio_shockwave, bio_teleport, bio_time_freeze, bio_tools, bio_torsionratchet, bio_water_extractor, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, item::charges, choose_adjacent(), clear_npc_ai_info_cache(), colorize(), sounds::combat, conduct_blood_analysis(), liquid_handler::consume_liquid(), convert_velocity(), shockwave_data::dam_mult, disp_name(), dispose_item(), effect_adrenaline, effect_badpoison, effect_bloodworms, effect_cig, effect_cocaine_high, effect_datura, effect_dermatik, effect_drunk, effect_fungus, effect_hallu, effect_iodine, effect_meth, effect_pblue, effect_pkill1, effect_pkill2, effect_pkill3, effect_pkill_l, effect_poison, effect_stung, effect_teleglow, effect_took_flumed, effect_took_prozac, effect_took_prozac_bad, effect_took_xanax, effect_visuals, effect_weed_high, explosion_handler::emp_blast(), bionic_data::enchantments, item_stack::end(), dealt_projectile_attack::end_point, enough_power_for(), map_stack::erase(), f_null, bionic_data::fake_item, fd_fire, avatar_action::fire_ranged_bionic(), avatar_action::fire_wielded_weapon(), flag_BIONIC_GUN, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, flag_CABLE_SPOOL(), flag_NO_UNWIELD(), flag_SEALED(), explosion_handler::flashbang(), shockwave_data::force, force_comedown(), units::from_kilojoule(), g, get_dirstring(), Creature::get_effect(), get_local_humidity(), get_local_windchill(), get_local_windpower(), get_lockpicking_open_result(), get_map(), get_player_character(), get_power_level(), weather_manager::get_precise(), get_rad(), Creature::get_value(), get_weather(), global_omt_location(), has_active_bionic(), Creature::has_effect(), bionic_data::has_flag(), Creature::has_flag(), item::has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), w_point::humidity, bionic::id, ideal_weapon_value, projectile::impact, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), item::invlet, invoke_item(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), is_mounted(), Creature::is_player(), bionic_data::is_remote_fueled, visitable< Character >::items_with(), itype_water_clean, m_bad, m_good, m_info, m_mixed, m_neutral, martial_arts_data, Creature::mod_moves(), mod_power_level(), my_bionics, bionic_data::name, lockpicking_open_result::new_furn_type, lockpicking_open_result::new_ter_type, one_in(), lockpicking_open_result::open_message, overmap_buffer, damage_instance::physical(), pos(), bionic_data::power_activate, bionic::powered, w_point::pressure, primary_weapon(), print_humidity(), print_pressure(), print_temperature(), projectile_attack(), query_yn(), shockwave_data::radius, projectile::range, recalculate_enchantment_cache(), Creature::remove_effect(), reset(), reset_encumbrance(), rl_dist(), rng(), sees(), set_painkiller(), set_power_level(), set_primary_weapon(), set_stim(), explosion_handler::shockwave(), sounds::sound(), projectile::speed, calendar::start_of_cataclysm, string_format(), shockwave_data::stun, behavior::success, t_null, teleport::teleport(), w_point::temperature, overmapbuffer::ter(), units::to_fahrenheit(), units::to_kilojoule(), calendar::turn, velocity_units(), VU_WIND, and weight_capacity().

Referenced by npc::activate_bionic_by_id(), add_bionic(), show_bionics_ui(), and npc::use_bionic_by_id().

◆ activate_mutation()

void Character::activate_mutation ( const trait_id mutation)

Definition at line 468 of file mutation.cpp.

469{
470 const mutation_branch &mdata = mut.obj();
471 char_trait_data &tdata = my_mutations[mut];
472 // You can take yourself halfway to Near Death levels of hunger/thirst.
473 // Fatigue can go to Exhausted.
474 if( !can_use_mutation_warn( mut, *this ) ) {
475 return;
476 }
478 tdata.powered = true;
479
480 if( !mut->enchantments.empty() ) {
482 }
483
484 if( mdata.transform ) {
485 const cata::value_ptr<mut_transform> trans = mdata.transform;
486 mod_moves( - trans->moves );
487 switch_mutations( mut, trans->target, trans->active );
488 return;
489 }
490
491 if( mut == trait_WEB_WEAVER ) {
492 g->m.add_field( pos(), fd_web, 1 );
493 add_msg_if_player( _( "You start spinning web with your spinnerets!" ) );
494 } else if( mut == trait_BURROW ) {
495 tdata.powered = false;
496 item burrowing_item( itype_id( "fake_burrowing" ) );
497 invoke_item( &burrowing_item );
498 return; // handled when the activity finishes
499 } else if( mut == trait_SLIMESPAWNER ) {
500 monster *const slime = g->place_critter_around( mtype_id( "mon_player_blob" ), pos(), 1 );
501 if( !slime ) {
502 // Oops, no room to divide!
503 add_msg_if_player( m_bad, _( "You focus, but are too hemmed in to birth a new slimespring!" ) );
504 tdata.powered = false;
505 return;
506 }
508 _( "You focus, and with a pleasant splitting feeling, birth a new slimespring!" ) );
509 slime->friendly = -1;
510 if( one_in( 3 ) ) {
512 //~ Usual enthusiastic slimespring small voices! :D
513 _( "wow! you look just like me! we should look out for each other!" ) );
514 } else if( one_in( 2 ) ) {
515 //~ Usual enthusiastic slimespring small voices! :D
516 add_msg_if_player( m_good, _( "come on, big me, let's go!" ) );
517 } else {
518 //~ Usual enthusiastic slimespring small voices! :D
519 add_msg_if_player( m_good, _( "we're a team, we've got this!" ) );
520 }
521 tdata.powered = false;
522 return;
523 } else if( mut == trait_NAUSEA || mut == trait_VOMITOUS ) {
524 vomit();
525 tdata.powered = false;
526 return;
527 } else if( mut == trait_M_FERTILE ) {
528 spores();
529 tdata.powered = false;
530 return;
531 } else if( mut == trait_M_BLOOM ) {
532 blossoms();
533 tdata.powered = false;
534 return;
535 } else if( mut == trait_M_PROVENANCE ) {
536 spores(); // double trouble!
537 blossoms();
538 tdata.powered = false;
539 return;
540 } else if( mut == trait_SELFAWARE ) {
541 print_health();
542 tdata.powered = false;
543 return;
544 } else if( mut == trait_TREE_COMMUNION ) {
545 tdata.powered = false;
546 if( !overmap_buffer.ter( global_omt_location() ).obj().is_wooded() ) {
547 add_msg_if_player( m_info, _( "You can only do that in a wooded area." ) );
548 return;
549 }
550 // Check for adjacent trees.
551 bool adjacent_tree = false;
552 for( const tripoint &p2 : g->m.points_in_radius( pos(), 1 ) ) {
553 if( g->m.has_flag( "TREE", p2 ) ) {
554 adjacent_tree = true;
555 }
556 }
557 if( !adjacent_tree ) {
558 add_msg_if_player( m_info, _( "You can only do that next to a tree." ) );
559 return;
560 }
561
563 add_msg_if_player( _( "You reach out to the trees with your roots." ) );
564 } else {
566 _( "You lay next to the trees letting your hair roots tangle with the trees." ) );
567 }
568
570
572 const time_duration startup_time = has_trait( trait_ROOTS3 ) ? rng( 15_minutes,
573 30_minutes ) : rng( 60_minutes, 90_minutes );
574 activity.values.push_back( to_turns<int>( startup_time ) );
575 return;
576 } else {
577 const time_duration startup_time = rng( 120_minutes, 180_minutes );
578 activity.values.push_back( to_turns<int>( startup_time ) );
579 return;
580 }
581 } else if( !mdata.spawn_item.is_empty() ) {
582 item tmpitem( mdata.spawn_item );
583 i_add_or_drop( tmpitem );
585 tdata.powered = false;
586 return;
587 } else if( !mdata.ranged_mutation.is_empty() ) {
590 tdata.powered = false;
591 return;
592 }
593}
mutation_collection my_mutations
Traits / mutations of the character.
Definition: character.h:2153
player_activity activity
Definition: character.h:1576
void vomit()
Handles Character vomiting effects.
Definition: character.cpp:7704
void print_health() const
Definition: character.cpp:4220
void blossoms()
Definition: character.cpp:8797
void switch_mutations(const trait_id &switched, const trait_id &target, bool start_powered)
Unset switched mutation and set target mutation instead.
Definition: mutation.cpp:182
void spores()
Definition: character.cpp:8783
bool i_add_or_drop(item &it, int qty=1)
Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.
Definition: character.cpp:2408
void mutation_spend_resources(const trait_id &mut)
Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated...
Definition: mutation.cpp:1698
void assign_activity(const activity_id &type, int moves=calendar::INDEFINITELY_LONG, int index=-1, int pos=INT_MIN, const std::string &name="")
Legacy activity assignment, does not work for any activites using the new activity_actor class and ma...
Definition: character.cpp:9196
This class is essentially a copyable unique pointer.
Definition: value_ptr.h:19
int friendly
Definition: monster.h:471
std::vector< int > values
A duration defined as a number of specific time units.
Definition: calendar.h:180
field_type_id fd_web
Definition: field_type.cpp:340
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_M_FERTILE("M_FERTILE")
static const trait_id trait_BURROW("BURROW")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const trait_id trait_ROOTS2("ROOTS2")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
bool can_use_mutation_warn(const trait_id &mut, const Character &character)
Calls can_use_mutation and if it fails, print a standard message.
Definition: mutation.cpp:1687
static const trait_id trait_M_BLOOM("M_BLOOM")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_SELFAWARE("SELFAWARE")
static const trait_id trait_NAUSEA("NAUSEA")
static const trait_id trait_M_PROVENANCE("M_PROVENANCE")
static const trait_id trait_TREE_COMMUNION("TREE_COMMUNION")
static const trait_id trait_ROOTS3("ROOTS3")
void fire_ranged_mutation(avatar &you, const item &fake_gun)
Stores fake gun specified by the mutation and starts interactive aiming.
bool powered
Whether the mutation is activated.
Definition: character.h:210
std::string ranged_mutation_message() const
std::string spawn_item_message() const
cata::value_ptr< mut_transform > transform
Definition: mutation.h:155
itype_id spawn_item
The item, if any, spawned by the mutation.
Definition: mutation.h:207
itype_id ranged_mutation
The fake gun, if any, spawned and fired by the ranged mutation.
Definition: mutation.h:245

References _, ACT_TREE_COMMUNION, activity, Creature::add_msg_if_player(), assign_activity(), blossoms(), can_use_mutation_warn(), mutation_branch::enchantments, fd_web, avatar_action::fire_ranged_mutation(), monster::friendly, g, global_omt_location(), has_trait(), i_add_or_drop(), invoke_item(), string_id< T >::is_empty(), itype_id, m_bad, m_good, m_info, Creature::mod_moves(), mtype_id, mutation_spend_resources(), my_mutations, string_id< T >::obj(), one_in(), overmap_buffer, pos(), char_trait_data::powered, print_health(), mutation_branch::ranged_mutation, mutation_branch::ranged_mutation_message(), recalculate_enchantment_cache(), rng(), mutation_branch::spawn_item, mutation_branch::spawn_item_message(), spores(), switch_mutations(), overmapbuffer::ter(), trait_BURROW, trait_M_BLOOM, trait_M_FERTILE, trait_M_PROVENANCE, trait_NAUSEA, trait_ROOTS2, trait_ROOTS3, trait_SELFAWARE, trait_SLIMESPAWNER, trait_TREE_COMMUNION, trait_VOMITOUS, trait_WEB_WEAVER, mutation_branch::transform, player_activity::values, and vomit().

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ active_light()

float Character::active_light ( ) const

Returns character luminosity based on the brightest active item they are carrying.

Definition at line 6316 of file character.cpp.

6317{
6318 float lumination = 0;
6319
6320 int maxlum = 0;
6321 has_item_with( [&maxlum]( const item & it ) {
6322 const int lumit = it.getlight_emit();
6323 if( maxlum < lumit ) {
6324 maxlum = lumit;
6325 }
6326 return false; // continue search, otherwise has_item_with would cancel the search
6327 } );
6328
6329 lumination = static_cast<float>( maxlum );
6330
6331 float mut_lum = 0.0f;
6332 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
6333 if( mut.second.powered ) {
6334 float curr_lum = 0.0f;
6335 for( const auto elem : mut.first->lumination ) {
6336 int coverage = 0;
6337 for( const item &i : worn ) {
6338 if( i.covers( elem.first ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
6339 !i.has_flag( flag_SEMITANGIBLE ) &&
6340 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
6341 coverage += i.get_coverage();
6342 }
6343 }
6344 curr_lum += elem.second * ( 1 - ( coverage / 100.0f ) );
6345 }
6346 mut_lum += curr_lum;
6347 }
6348 }
6349
6350 lumination = std::max( lumination, mut_lum );
6351
6352 if( lumination < 60 && has_active_bionic( bio_flashlight ) ) {
6353 lumination = 60;
6354 } else if( lumination < 25 && has_artifact_with( AEP_GLOW ) ) {
6355 lumination = 25;
6356 } else if( lumination < 5 && ( has_effect( effect_glowing ) ||
6358 has_effect( effect_glowy_led ) ) ) ) {
6359 lumination = 5;
6360 }
6361 return lumination;
6362}
static const efftype_id effect_glowy_led("glowy_led")
static const bionic_id bio_flashlight("bio_flashlight")
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const efftype_id effect_glowing("glowing")
static const std::string flag_AURA("AURA")
static const bionic_id bio_tattoo_led("bio_tattoo_led")
static const std::string flag_PERSONAL("PERSONAL")
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3213
int getlight_emit() const
How much light (see lightmap.cpp) the item emits (it's assumed to be circular).
Definition: item.cpp:8386
bool has_item_with(const std::function< bool(const item &)> &filter) const
Returns true if any item (including those within a container) matches the filter.
Definition: visitable.cpp:105
@ AEP_GLOW
Definition: enums.h:115

References AEP_GLOW, bio_flashlight, bio_tattoo_led, effect_glowing, effect_glowy_led, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), item::getlight_emit(), has_active_bionic(), has_artifact_with(), Creature::has_effect(), visitable< Character >::has_item_with(), my_mutations, and worn.

Referenced by map::apply_character_light(), and character_funcs::fine_detail_vision_mod().

◆ add_addiction()

void Character::add_addiction ( add_type  type,
int  strength 
)

Adds an addiction to the player.

Definition at line 1844 of file suffer.cpp.

1845{
1846 if( type == add_type::NONE ) {
1847 return;
1848 }
1849 time_duration timer = 2_hours;
1850 if( has_trait( trait_ADDICTIVE ) ) {
1851 strength *= 2;
1852 timer = 1_hours;
1853 } else if( has_trait( trait_NONADDICTIVE ) ) {
1854 strength /= 2;
1855 timer = 6_hours;
1856 }
1857 //Update existing addiction
1858 for( auto &i : addictions ) {
1859 if( i.type != type ) {
1860 continue;
1861 }
1862
1863 if( i.sated < 0_turns ) {
1864 i.sated = timer;
1865 } else if( i.sated < 10_minutes ) {
1866 // TODO: Make this variable?
1867 i.sated += timer;
1868 } else {
1869 i.sated += timer / 2;
1870 }
1871 if( i.intensity < MAX_ADDICTION_LEVEL && strength > i.intensity * rng( 2, 5 ) ) {
1872 i.intensity++;
1873 }
1874
1875 add_msg( m_debug, "Updating addiction: %d intensity, %d sated",
1876 i.intensity, to_turns<int>( i.sated ) );
1877
1878 return;
1879 }
1880
1881 // Add a new addiction
1882 const int roll = rng( 0, 100 );
1883 add_msg( m_debug, "Addiction: roll %d vs strength %d", roll, strength );
1884 if( roll < strength ) {
1885 const std::string &type_name = addiction_type_name( type );
1886 add_msg( m_debug, "%s got addicted to %s", disp_name(), type_name );
1887 addictions.emplace_back( type, 1 );
1888 g->events().send<event_type::gains_addiction>( getID(), type );
1889 }
1890}
std::string addiction_type_name(add_type const cur)
Returns the name of an addiction.
Definition: addiction.cpp:253
constexpr int MAX_ADDICTION_LEVEL
Definition: addiction.h:14
std::vector< addiction > addictions
Definition: character.h:1605
character_id getID() const
Definition: character.cpp:494
@ m_debug
Definition: enums.h:271
static const trait_id trait_NONADDICTIVE("NONADDICTIVE")
static const trait_id trait_ADDICTIVE("ADDICTIVE")

References add_msg(), addiction_type_name(), addictions, disp_name(), g, gains_addiction, getID(), has_trait(), m_debug, MAX_ADDICTION_LEVEL, NONE, rng(), trait_ADDICTIVE, trait_NONADDICTIVE, and type.

Referenced by iexamine::flower_poppy(), marloss_common(), and modify_addiction().

◆ add_bionic()

void Character::add_bionic ( const bionic_id b)

Adds a bionic to my_bionics[].

Definition at line 2580 of file bionics.cpp.

2581{
2582 if( has_bionic( b ) ) {
2583 debugmsg( "Tried to install bionic %s that is already installed!", b.c_str() );
2584 return;
2585 }
2586
2587 const units::energy pow_up = b->capacity;
2588 mod_max_power_level( pow_up );
2590 add_msg_if_player( m_good, _( "Increased storage capacity by %i." ),
2591 units::to_kilojoule( pow_up ) );
2592 // Power Storage CBMs are not real bionic units, so return without adding it to my_bionics
2593 return;
2594 }
2595
2596 my_bionics->push_back( bionic( b, get_free_invlet( *my_bionics ) ) );
2597 if( b == bio_tools || b == bio_ears ) {
2598 activate_bionic( my_bionics->back() );
2599 }
2600
2601 for( const bionic_id &inc_bid : b->included_bionics ) {
2602 add_bionic( inc_bid );
2603 }
2604
2605 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2606 const spell_id learned_spell = spell_pair.first;
2607 if( learned_spell->spell_class != trait_id( "NONE" ) ) {
2608 const trait_id spell_class = learned_spell->spell_class;
2609 // spells you learn from a bionic overwrite the opposite spell class.
2610 // for best UX, include those spell classes in "canceled_mutations"
2611 if( !has_trait( spell_class ) ) {
2612 set_mutation( spell_class );
2613 on_mutation_gain( spell_class );
2614 add_msg_if_player( spell_class->desc() );
2615 }
2616 }
2617 if( !magic->knows_spell( learned_spell ) ) {
2618 magic->learn_spell( learned_spell, *this, true );
2619 }
2620 spell &known_spell = magic->get_spell( learned_spell );
2621 // spells you learn from installing a bionic upgrade spells you know if they are the same
2622 if( known_spell.get_level() < spell_pair.second ) {
2623 known_spell.set_level( spell_pair.second );
2624 }
2625 }
2626
2629 if( !b->enchantments.empty() ) {
2631 }
2632}
static const bionic_id bio_power_storage("bio_power_storage")
static const bionic_id bio_power_storage_mkII("bio_power_storage_mkII")
char get_free_invlet(bionic_collection &bionics)
Definition: bionics_ui.cpp:177
void mod_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1937
bool activate_bionic(bionic &bio, bool eff_only=false)
Handles bionic activation effects of the entered bionic, returns if anything activated.
Definition: bionics.cpp:588
void on_mutation_gain(const trait_id &mid)
Called when a mutation is gained.
Definition: character.cpp:9900
bool has_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id.
Definition: character.cpp:1815
void add_bionic(const bionic_id &b)
Adds a bionic to my_bionics[].
Definition: bionics.cpp:2580
void recalc_sight_limits()
Modifies the player's sight values Must be called when any of the following change: This must be call...
Definition: character.cpp:1630
void set_mutation(const trait_id &)
Add or removes a mutation on the player, but does not trigger mutation loss/gain effects.
Definition: mutation.cpp:152
pimpl< known_magic > magic
Definition: character.h:1483
trait_id spell_class
Definition: magic.h:236
Definition: magic.h:286
int get_level() const
Definition: magic.cpp:1034
void set_level(int nlevel)
Definition: magic.cpp:612
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:75
constexpr double b
Definition: magic.cpp:1031
std::string desc() const

References _, activate_bionic(), add_bionic(), Creature::add_msg_if_player(), b, bio_ears, bio_power_storage, bio_power_storage_mkII, bio_tools, debugmsg, mutation_branch::desc(), get_free_invlet(), spell::get_level(), has_bionic(), has_trait(), m_good, magic, mod_max_power_level(), my_bionics, on_mutation_gain(), recalc_sight_limits(), recalculate_enchantment_cache(), reset_encumbrance(), spell::set_level(), set_mutation(), spell_type::spell_class, and units::to_kilojoule().

Referenced by add_bionic(), bionics_install_failure(), avatar::create(), deactivate_bionic(), player::load(), perform_install(), and npc::randomize().

◆ add_known_trap()

void Character::add_known_trap ( const tripoint pos,
const trap t 
)

Definition at line 10259 of file character.cpp.

10260{
10261 const tripoint p = get_map().getabs( pos );
10262 if( t.is_null() ) {
10263 known_traps.erase( p );
10264 } else {
10265 // TODO: known_traps should map to a trap_str_id
10266 known_traps[p] = t.id.str();
10267 }
10268}
trap_map known_traps
Definition: character.h:2144
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8407
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:263
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
trap_str_id id
Definition: trap.h:87

References get_map(), map::getabs(), trap::id, trap::is_null(), known_traps, pos(), and string_id< T >::str().

Referenced by vehicle::handle_trap(), place_and_add_as_known(), and character_funcs::search_surroundings().

◆ add_miss_reason()

void Character::add_miss_reason ( const std::string &  reason,
unsigned int  weight 
)

Adds a reason for why the player would miss a melee attack.

To possibly be messaged to the player when he misses a melee attack.

Parameters
reasonA message for the player that gives a reason for him missing.
weightThe weight used when choosing what reason to pick when the player misses.

Definition at line 379 of file melee.cpp.

380{
381 melee_miss_reasons.add( reason, weight );
382
383}
struct weighted_int_list< std::string > melee_miss_reasons
Definition: character.h:2269

References melee_miss_reasons.

Referenced by temperature_effect::apply(), eff_fun_hallu(), get_miss_reason(), hardcoded_effects(), process_one_effect(), reset_stats(), and suffer_in_sunlight().

◆ add_morale()

void Character::add_morale ( const morale_type type,
int  bonus,
int  max_bonus = 0,
const time_duration duration = 1_hours,
const time_duration decay_start = 30_minutes,
bool  capped = false,
const itype item_type = nullptr 
)

Definition at line 9098 of file character.cpp.

9101{
9102 if( item_type != nullptr ) {
9103 morale->add( type, bonus, max_bonus, duration, decay_start, capped, *item_type );
9104 } else {
9105 morale->add( type, bonus, max_bonus, duration, decay_start, capped );
9106 }
9107}
pimpl< player_morale > morale
Definition: character.h:2206

References morale, and type.

Referenced by addict_effect(), apply_persistent_morale(), apply_wetness_morale(), iuse::artifact(), iuse::bell(), iuse::blech(), debug_menu::character_edit_menu(), iuse::datura(), monster::die(), avatar::do_read(), iuse::einktabletpc(), npc::finish_read(), ranged::fire_gun(), activity_handlers::generic_game_do_turn(), activity_handlers::haircut_finish(), hardcoded_effects(), marloss_add(), marloss_common(), activity_handlers::meditate_finish(), modify_morale(), spell_effect::morale(), iuse::mycus(), iuse::plantblech(), iuse::play_music(), activity_handlers::play_with_pet_finish(), iuse::portable_game(), game::process_artifact(), process_bionic(), firestarter_actor::resolve_firestarter_use(), set_up_butchery_activity(), activity_handlers::shaving_finish(), game::start_game(), suffer_feral_kill_withdrawl(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_schizophrenia(), suffer_while_awake(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), enzlave_actor::use(), musical_instrument_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), activity_handlers::vibe_do_turn(), activity_handlers::vibe_finish(), and avatar::vomit().

◆ addiction_level()

int Character::addiction_level ( add_type  type) const

Returns the intensity of the specified addiction.

Definition at line 1913 of file suffer.cpp.

1914{
1915 auto iter = std::find_if( addictions.begin(), addictions.end(),
1916 [type]( const addiction & ad ) {
1917 return ad.type == type;
1918 } );
1919 return iter != addictions.end() ? iter->intensity : 0;
1920}

References addictions, and type.

Referenced by iuse::ecig(), process_one_effect(), and iuse::smoking().

◆ adjust_for_focus()

int Character::adjust_for_focus ( int  amount) const

Definition at line 9943 of file character.cpp.

9944{
9945 int effective_focus = focus_pool;
9946 if( has_trait( trait_FASTLEARNER ) ) {
9947 effective_focus += 15;
9948 }
9949 if( has_active_bionic( bio_memory ) ) {
9950 effective_focus += 10;
9951 }
9952 if( has_trait( trait_SLOWLEARNER ) ) {
9953 effective_focus -= 15;
9954 }
9955 effective_focus += ( get_int() - get_option<int>( "INT_BASED_LEARNING_BASE_VALUE" ) ) *
9956 get_option<int>( "INT_BASED_LEARNING_FOCUS_ADJUSTMENT" );
9957 double tmp = amount * ( effective_focus / 100.0 );
9958 return roll_remainder( tmp );
9959}
static const trait_id trait_FASTLEARNER("FASTLEARNER")
static const bionic_id bio_memory("bio_memory")
static const trait_id trait_SLOWLEARNER("SLOWLEARNER")
int focus_pool
Definition: character.h:1596
virtual int get_int() const
Definition: character.cpp:4101

References bio_memory, focus_pool, get_int(), has_active_bionic(), has_trait(), roll_remainder(), trait_FASTLEARNER, and trait_SLOWLEARNER.

Referenced by spell::casting_exp(), avatar::do_read(), and practice().

◆ age()

int Character::age ( ) const

Definition at line 6800 of file character.cpp.

6801{
6802 int years_since_cataclysm = to_turns<int>( calendar::turn - calendar::turn_zero ) /
6803 to_turns<int>( calendar::year_length() );
6804 return init_age + years_since_cataclysm;
6805}
int init_age
age in years at character creation
Definition: character.h:2138
time_duration year_length()
Definition: calendar.cpp:461
const time_point turn_zero
Represents time point 0.
Definition: calendar.cpp:26

References init_age, calendar::turn, calendar::turn_zero, and calendar::year_length().

Referenced by age_string(), and set_base_age().

◆ age_string()

std::string Character::age_string ( ) const

Definition at line 6807 of file character.cpp.

6808{
6809 //~ how old the character is in years. try to limit number of characters to fit on the screen
6810 std::string unformatted = _( "%d years" );
6811 return string_format( unformatted, age() );
6812}
int age() const
Definition: character.cpp:6800

References _, age(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ all_items_with_flag()

std::vector< const item * > Character::all_items_with_flag ( const std::string &  flag) const

All items that have the given flag (item::has_flag).

Definition at line 9601 of file character.cpp.

9602{
9603 return items_with( [&flag]( const item & it ) {
9604 return it.has_flag( flag );
9605 } );
9606}

References item::has_flag(), and visitable< Character >::items_with().

Referenced by iexamine::choose_fertilizer(), iexamine::dimensional_portal(), has_fire(), and use_fire().

◆ allergy_type()

morale_type Character::allergy_type ( const item food) const

Returns allergy type or MORALE_NULL if not allergic for this character.

Definition at line 619 of file consumption.cpp.

620{
621 using allergy_tuple = std::tuple<trait_id, std::string, morale_type>;
622 static const std::array<allergy_tuple, 8> allergy_tuples = {{
629 }
630 };
631
632 for( const auto &tp : allergy_tuples ) {
633 if( has_trait( std::get<0>( tp ) ) &&
634 food.has_flag( std::get<1>( tp ) ) ) {
635 return std::get<2>( tp );
636 }
637 }
638
639 return MORALE_NULL;
640}
static const std::string flag_ALLERGEN_MILK("ALLERGEN_MILK")
static const std::string flag_ALLERGEN_VEGGY("ALLERGEN_VEGGY")
static const std::string flag_ALLERGEN_JUNK("ALLERGEN_JUNK")
static const std::string flag_ALLERGEN_FRUIT("ALLERGEN_FRUIT")
static const trait_id trait_ANTIWHEAT("ANTIWHEAT")
static const trait_id trait_ANTIJUNK("ANTIJUNK")
static const trait_id trait_VEGETARIAN("VEGETARIAN")
static const trait_id trait_LACTOSE("LACTOSE")
static const std::string flag_ALLERGEN_WHEAT("ALLERGEN_WHEAT")
static const std::string flag_ALLERGEN_MEAT("ALLERGEN_MEAT")
static const trait_id trait_MEATARIAN("MEATARIAN")
static const trait_id trait_ANTIFRUIT("ANTIFRUIT")
const morale_type MORALE_MEATARIAN("morale_meatarian")
const morale_type MORALE_ANTIJUNK("morale_antijunk")
const morale_type MORALE_ANTIWHEAT("morale_antiwheat")
const morale_type MORALE_ANTIFRUIT("morale_antifruit")
const morale_type MORALE_LACTOSE("morale_lactose")
const morale_type MORALE_VEGETARIAN("morale_vegetarian")
const morale_type MORALE_NULL("morale_null")

References flag_ALLERGEN_FRUIT(), flag_ALLERGEN_JUNK(), flag_ALLERGEN_MEAT(), flag_ALLERGEN_MILK(), flag_ALLERGEN_VEGGY(), flag_ALLERGEN_WHEAT(), item::has_flag(), has_trait(), MORALE_ANTIFRUIT, MORALE_ANTIJUNK, MORALE_ANTIWHEAT, MORALE_LACTOSE, MORALE_MEATARIAN, MORALE_NULL, MORALE_VEGETARIAN, trait_ANTIFRUIT, trait_ANTIJUNK, trait_ANTIWHEAT, trait_LACTOSE, trait_MEATARIAN, and trait_VEGETARIAN.

Referenced by item::color_in_inventory(), item::food_info(), modify_morale(), and will_eat().

◆ allocated_invlets()

invlets_bitset Character::allocated_invlets ( ) const

Only use for UI things.

Returns all invlets that are currently used in the player inventory, the weapon slot and the worn items.

Definition at line 2495 of file character.cpp.

2496{
2498
2499 const item &weapon = primary_weapon();
2500 invlets.set( weapon.invlet );
2501 for( const auto &w : worn ) {
2502 invlets.set( w.invlet );
2503 }
2504
2505 invlets[0] = false;
2506
2507 return invlets;
2508}
inventory inv
Definition: character.h:1579
invlets_bitset allocated_invlets() const
Definition: inventory.cpp:1262
std::bitset< std::numeric_limits< char >::max()> invlets_bitset
Definition: inventory.h:36

References inventory::allocated_invlets(), inv, item::invlet, primary_weapon(), and worn.

Referenced by inventory::assign_empty_invlet(), game_menus::inv::common(), and i_add().

◆ amount_of_storage_bionics()

std::pair< int, int > Character::amount_of_storage_bionics ( ) const

Returns amount of Storage CBMs in the corpse.

Definition at line 2676 of file bionics.cpp.

2677{
2679
2680 // exclude amount of power capacity obtained via non-power-storage CBMs
2681 for( const bionic &it : *my_bionics ) {
2682 lvl -= it.info().capacity;
2683 }
2684
2685 std::pair<int, int> results( 0, 0 );
2686 if( lvl <= 0_kJ ) {
2687 return results;
2688 }
2689
2690 const units::energy pow_mkI = bio_power_storage->capacity;
2692
2693 while( lvl >= std::min( pow_mkI, pow_mkII ) ) {
2694 if( one_in( 2 ) ) {
2695 if( lvl >= pow_mkI ) {
2696 results.first++;
2697 lvl -= pow_mkI;
2698 }
2699 } else {
2700 if( lvl >= pow_mkII ) {
2701 results.second++;
2702 lvl -= pow_mkII;
2703 }
2704 }
2705 }
2706 return results;
2707}
units::energy get_max_power_level() const
Definition: character.cpp:1910
units::energy capacity
Power bank size.
Definition: bionics.h:49

References bio_power_storage, bio_power_storage_mkII, bionic_data::capacity, get_max_power_level(), my_bionics, and one_in().

Referenced by place_corpse().

◆ amount_worn()

int Character::amount_worn ( const itype_id id) const

Returns the amount of item ‘type’ that is currently worn.

Definition at line 2188 of file character.cpp.

2189{
2190 int amount = 0;
2191 for( auto &elem : worn ) {
2192 if( elem.typeId() == id ) {
2193 ++amount;
2194 }
2195 }
2196 return amount;
2197}

References worn.

Referenced by can_wear().

◆ apply_damage()

void Character::apply_damage ( Creature source,
bodypart_id  hurt,
int  dam,
bool  bypass_med = false 
)
overridevirtual

Actually hurt the player, hurts a body_part directly, no armor reduction.

Implements Creature.

Definition at line 8409 of file character.cpp.

8411{
8413 // don't do any more damage if we're already dead
8414 // Or if we're debugging and don't want to die
8415 return;
8416 }
8417
8418 if( hurt == bodypart_id( "num_bp" ) ) {
8419 debugmsg( "Wacky body part hurt!" );
8420 hurt = bodypart_id( "torso" );
8421 }
8422
8423 mod_pain( dam / 2 );
8424
8425 const bodypart_id &part_to_damage = hurt->main_part;
8426
8427 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( part_to_damage ) );
8428
8429 mod_part_hp_cur( part_to_damage, - dam_to_bodypart );
8431
8432 const item &weapon = primary_weapon();
8433 if( !weapon.is_null() && !as_player()->can_wield( weapon ).success() &&
8434 can_unwield( weapon ).success() ) {
8435 add_msg_if_player( _( "You are no longer able to wield your %s and drop it!" ),
8436 weapon.display_name() );
8438 i_rem( &weapon );
8439 }
8440
8441 if( dam > get_painkiller() ) {
8442 on_hurt( source );
8443 }
8444
8445 if( is_dead_state() ) {
8446 // if the player killed himself, add it to the kill count list
8447 if( !is_npc() && !killer && source == g->u.as_character() ) {
8449 get_name() );
8450 }
8451 set_killer( source );
8452 }
8453
8454 if( !bypass_med ) {
8455 // remove healing effects if damaged
8456 int remove_med = roll_remainder( dam / 5.0f );
8457 if( remove_med > 0 && has_effect( effect_bandaged, part_to_damage->token ) ) {
8458 remove_med -= reduce_healing_effect( effect_bandaged, remove_med, part_to_damage );
8459 }
8460 if( remove_med > 0 && has_effect( effect_disinfected, part_to_damage->token ) ) {
8461 reduce_healing_effect( effect_disinfected, remove_med, part_to_damage );
8462 }
8463 }
8464}
void put_into_vehicle_or_drop(Character &c, item_drop_reason, const std::list< item > &items)
static const trait_id trait_DEBUG_NODMG("DEBUG_NODMG")
static const efftype_id effect_bandaged("bandaged")
static const efftype_id effect_disinfected("disinfected")
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:764
int get_painkiller() const
Returns intensity of painkillers
Definition: character.cpp:9814
item i_rem(int pos)
Remove a specific item from player possession.
Definition: character.cpp:2373
int reduce_healing_effect(const efftype_id &eff_id, int remove_med, const bodypart_id &hurt)
Reduce healing effect intensity, return initial intensity of the effect.
Definition: character.cpp:8623
void on_hurt(Creature *source, bool disturb=true)
Handles effects that happen when the player is damaged and aware of the fact.
Definition: character.cpp:8699
ret_val< bool > can_wield(const item &it) const
Check whether character is capable of wielding given item.
Definition: character.cpp:3090
ret_val< bool > can_unwield(const item &it) const
Check whether character is capable of unwielding given item.
Definition: character.cpp:3126
bool is_dead_state() const override
Returns true if the character should be dead.
Definition: character.cpp:499
std::string get_name() const override
Definition: character.cpp:6004
void mod_part_hp_cur(const bodypart_id &id, int mod)
Definition: creature.cpp:1637
int get_part_hp_cur(const bodypart_id &id) const
Definition: creature.cpp:1607
virtual player * as_player()
Definition: creature.h:122
void set_killer(Creature *killer)
Definition: creature.cpp:1472
virtual bool is_npc() const
Definition: creature.h:98
Creature * killer
Definition: creature.h:812
void send(const cata::event &) const
Definition: event_bus.cpp:58
@ character_takes_damage
@ character_kills_character
event_bus & get_event_bus()
Definition: game.cpp:12111

References _, Creature::add_msg_if_player(), Creature::as_player(), can_unwield(), can_wield(), character_kills_character, character_takes_damage, debugmsg, effect_bandaged, effect_disinfected, g, get_event_bus(), get_name(), get_painkiller(), Creature::get_part_hp_cur(), get_player_character(), getID(), Creature::has_effect(), has_trait(), i_rem(), is_dead_state(), Creature::is_npc(), Creature::killer, mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), primary_weapon(), put_into_vehicle_or_drop(), reduce_healing_effect(), roll_remainder(), event_bus::send(), Creature::set_killer(), behavior::success, trait_DEBUG_NODMG, and tumbling.

Referenced by activate_bionic(), iuse::blech(), cough(), debug_menu::debug(), do_damage_for_bionic_failure(), eff_fun_bleed(), eff_fun_fungus(), iuse::ehandcuffs(), game::find_or_make_stairs(), heal_actor::finish_using(), iexamine::flower_cactus(), iexamine::flower_poppy(), game::handle_action(), start_location::handle_heli_crash(), hardcoded_effects(), knock_back_to(), activity_handlers::operation_do_turn(), process_one_effect(), suffer_from_sunburn(), suffer_water_damage(), and suffer_while_underwater().

◆ apply_mods()

void Character::apply_mods ( const trait_id mut,
bool  add_remove 
)
protected

Applies stat mods to character.

Definition at line 204 of file mutation.cpp.

205{
206 int sign = add_remove ? 1 : -1;
207 int str_change = get_mod( mut, "STR" );
208 str_max += sign * str_change;
209 per_max += sign * get_mod( mut, "PER" );
210 dex_max += sign * get_mod( mut, "DEX" );
211 int_max += sign * get_mod( mut, "INT" );
212
213 if( str_change != 0 ) {
214 recalc_hp();
215 }
216}
void recalc_hp()
Recalculates HP after a change to max strength.
Definition: character.cpp:1583
int get_mod(const trait_id &mut, const std::string &arg) const
Retrieves a stat mod of a mutation.
Definition: mutation.cpp:193

References dex_max, get_mod(), int_max, per_max, recalc_hp(), and str_max.

Referenced by deactivate_mutation(), mutation_effect(), mutation_loss_effect(), mutation_spend_resources(), and suffer_mutation_power().

◆ apply_persistent_morale()

void Character::apply_persistent_morale ( )

Ensures persistent morale effects are up-to-date.

Definition at line 9013 of file character.cpp.

9014{
9015 // Hoarders get a morale penalty if they're not carrying a full inventory.
9016 if( has_trait( trait_HOARDER ) ) {
9017 int pen = ( volume_capacity() - volume_carried() ) / 125_ml;
9018 if( pen > 70 ) {
9019 pen = 70;
9020 }
9021 if( pen <= 0 ) {
9022 pen = 0;
9023 }
9024 if( has_effect( effect_took_xanax ) ) {
9025 pen = pen / 7;
9026 } else if( has_effect( effect_took_prozac ) ) {
9027 pen = pen / 2;
9028 }
9029 if( pen > 0 ) {
9030 add_morale( MORALE_PERM_HOARDER, -pen, -pen, 1_minutes, 1_minutes, true );
9031 }
9032 }
9033 // Nomads get a morale penalty if they stay near the same overmap tiles too long.
9035 const tripoint_abs_omt ompos = global_omt_location();
9036 float total_time = 0;
9037 // Check how long we've stayed in any overmap tile within 5 of us.
9038 const int max_dist = 5;
9039 for( const tripoint_abs_omt &pos : points_in_radius( ompos, max_dist ) ) {
9040 const float dist = rl_dist( ompos, pos );
9041 if( dist > max_dist ) {
9042 continue;
9043 }
9044 const auto iter = overmap_time.find( pos.xy() );
9045 if( iter == overmap_time.end() ) {
9046 continue;
9047 }
9048 // Count time in own tile fully, tiles one away as 4/5, tiles two away as 3/5, etc.
9049 total_time += to_moves<float>( iter->second ) * ( max_dist - dist ) / max_dist;
9050 }
9051 // Characters with higher tiers of Nomad suffer worse morale penalties, faster.
9052 int max_unhappiness;
9053 float min_time, max_time;
9054 if( has_trait( trait_NOMAD ) ) {
9055 max_unhappiness = 20;
9056 min_time = to_moves<float>( 2_days );
9057 max_time = to_moves<float>( 4_days );
9058 } else if( has_trait( trait_NOMAD2 ) ) {
9059 max_unhappiness = 40;
9060 min_time = to_moves<float>( 1_days );
9061 max_time = to_moves<float>( 2_days );
9062 } else { // traid_NOMAD3
9063 max_unhappiness = 60;
9064 min_time = to_moves<float>( 12_hours );
9065 max_time = to_moves<float>( 1_days );
9066 }
9067 // The penalty starts at 1 at min_time and scales up to max_unhappiness at max_time.
9068 const float t = ( total_time - min_time ) / ( max_time - min_time );
9069 const int pen = std::ceil( lerp_clamped( 0, max_unhappiness, t ) );
9070 if( pen > 0 ) {
9071 add_morale( MORALE_PERM_NOMAD, -pen, -pen, 1_minutes, 1_minutes, true );
9072 }
9073 }
9074
9075 if( has_trait( trait_PROF_FOODP ) ) {
9076 // Loosing your face is distressing
9077 if( !( is_wearing( itype_id( "foodperson_mask" ) ) ||
9078 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
9079 add_morale( MORALE_PERM_NOFACE, -20, -20, 1_minutes, 1_minutes, true );
9080 } else if( is_wearing( itype_id( "foodperson_mask" ) ) ||
9081 is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9083 }
9084
9085 if( is_wearing( itype_id( "foodperson_mask_on" ) ) ) {
9086 add_morale( MORALE_PERM_FPMODE_ON, 10, 10, 1_minutes, 1_minutes, true );
9087 } else {
9089 }
9090 }
9091}
constexpr T lerp_clamped(const T &min, const T &max, float t)
Linear interpolation with t clamped to [0, 1].
Definition: cata_utility.h:166
static const efftype_id effect_took_prozac("took_prozac")
static const trait_id trait_PROF_FOODP("PROF_FOODP")
static const trait_id trait_HOARDER("HOARDER")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_took_xanax("took_xanax")
units::volume volume_capacity() const
Definition: character.cpp:2671
std::unordered_map< point_abs_omt, time_duration > overmap_time
Amount of time the player has spent in each overmap tile.
Definition: character.h:2285
units::volume volume_carried() const
Definition: character.cpp:2543
void add_morale(const morale_type &type, int bonus, int max_bonus=0, const time_duration &duration=1_hours, const time_duration &decay_start=30_minutes, bool capped=false, const itype *item_type=nullptr)
Definition: character.cpp:9098
void rem_morale(const morale_type &type)
Definition: character.cpp:9119
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3235
tripoint_range< Tripoint > points_in_radius(const Tripoint &center, const int radius, const int radiusz=0)
Definition: map_iterator.h:125
const morale_type MORALE_PERM_FPMODE_ON("morale_perm_fpmode_on")
const morale_type MORALE_PERM_HOARDER("morale_perm_hoarder")
const morale_type MORALE_PERM_NOMAD("morale_perm_nomad")
const morale_type MORALE_PERM_NOFACE("morale_perm_noface")
constexpr point xy() const
Definition: point.h:206

References add_morale(), effect_took_prozac, effect_took_xanax, global_omt_location(), Creature::has_effect(), has_trait(), is_wearing(), itype_id, lerp_clamped(), MORALE_PERM_FPMODE_ON, MORALE_PERM_HOARDER, MORALE_PERM_NOFACE, MORALE_PERM_NOMAD, overmap_time, points_in_radius(), pos(), rem_morale(), rl_dist(), trait_HOARDER, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, trait_PROF_FOODP, volume_capacity(), volume_carried(), and tripoint::xy().

Referenced by debug_menu::character_edit_menu(), check_and_recover_morale(), avatar::create(), and update_morale().

◆ apply_skill_boost()

void Character::apply_skill_boost ( )
private

Applies skill-based boosts to stats.

Definition at line 3569 of file character.cpp.

3570{
3571 for( const skill_boost &boost : skill_boost::get_all() ) {
3572 // For migration, reset previously applied bonus.
3573 // Remove after 0.E or so.
3574 const std::string bonus_name = boost.stat() + std::string( "_bonus" );
3575 std::string previous_bonus = get_value( bonus_name );
3576 if( !previous_bonus.empty() ) {
3577 if( boost.stat() == "str" ) {
3578 str_max -= atoi( previous_bonus.c_str() );
3579 } else if( boost.stat() == "dex" ) {
3580 dex_max -= atoi( previous_bonus.c_str() );
3581 } else if( boost.stat() == "int" ) {
3582 int_max -= atoi( previous_bonus.c_str() );
3583 } else if( boost.stat() == "per" ) {
3584 per_max -= atoi( previous_bonus.c_str() );
3585 }
3586 remove_value( bonus_name );
3587 }
3588 // End migration code
3589 int skill_total = 0;
3590 for( const std::string &skill_str : boost.skills() ) {
3591 skill_total += get_skill_level( skill_id( skill_str ) );
3592 }
3593 mod_stat( boost.stat(), boost.calc_bonus( skill_total ) );
3594 if( boost.stat() == "str" ) {
3595 recalc_hp();
3596 }
3597 }
3598}
void mod_stat(const std::string &stat, float modifier) override
Definition: character.cpp:546
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3350
void remove_value(const std::string &key)
Definition: creature.cpp:1377
static const std::vector< skill_boost > & get_all()
Definition: skill_boost.cpp:15

References dex_max, skill_boost::get_all(), get_skill_level(), Creature::get_value(), int_max, mod_stat(), per_max, recalc_hp(), Creature::remove_value(), skill_id, and str_max.

Referenced by reset_stats().

◆ apply_wetness_morale()

void Character::apply_wetness_morale ( int  temperature)

Recalculates morale penalty/bonus from wetness based on mutations, equipment and temperature.

Definition at line 1759 of file suffer.cpp.

1760{
1761 // First, a quick check if we have any wetness to calculate morale from
1762 // Faster than checking all worn items for friendliness
1763 if( !std::any_of( body_wetness.begin(), body_wetness.end(),
1764 []( const int w ) {
1765 return w != 0;
1766} ) ) {
1767 return;
1768 }
1769
1770 // Normalize temperature to [-1.0,1.0]
1771 temperature = std::max( 0, std::min( 100, temperature ) );
1772 const double global_temperature_mod = -1.0 + ( 2.0 * temperature / 100.0 );
1773
1774 int total_morale = 0;
1775 const auto wet_friendliness = exclusive_flag_coverage( "WATER_FRIENDLY" );
1776 for( const body_part bp : all_body_parts ) {
1777 // Sum of body wetness can go up to 103
1778 const int part_drench = body_wetness[bp];
1779 if( part_drench == 0 ) {
1780 continue;
1781 }
1782
1783 const auto &part_arr = mut_drench[bp];
1784 const int part_ignored = part_arr[WT_IGNORED];
1785 const int part_neutral = part_arr[WT_NEUTRAL];
1786 const int part_good = part_arr[WT_GOOD];
1787
1788 if( part_ignored >= part_drench ) {
1789 continue;
1790 }
1791
1792 int bp_morale = 0;
1793 const bool is_friendly = wet_friendliness.test( bp );
1794 const int effective_drench = part_drench - part_ignored;
1795 if( is_friendly ) {
1796 // Using entire bonus from mutations and then some "human" bonus
1797 bp_morale = std::min( part_good, effective_drench ) + effective_drench / 2;
1798 } else if( effective_drench < part_good ) {
1799 // Positive or 0
1800 // Won't go higher than part_good / 2
1801 // Wet slime/scale doesn't feel as good when covered by wet rags/fur/kevlar
1802 bp_morale = std::min( effective_drench, part_good - effective_drench );
1803 } else if( effective_drench > part_good + part_neutral ) {
1804 // This one will be negative
1805 bp_morale = part_good + part_neutral - effective_drench;
1806 }
1807
1808 // Clamp to [COLD,HOT] and cast to double
1809 const double part_temperature =
1810 std::min( BODYTEMP_HOT, std::max( BODYTEMP_COLD, temp_cur[bp] ) );
1811 // 0.0 at COLD, 1.0 at HOT
1812 const double part_mod = ( part_temperature - BODYTEMP_COLD ) /
1814 // Average of global and part temperature modifiers, each in range [-1.0, 1.0]
1815 double scaled_temperature = ( global_temperature_mod + part_mod ) / 2;
1816
1817 if( bp_morale < 0 ) {
1818 // Damp, hot clothing on hot skin feels bad
1819 scaled_temperature = std::fabs( scaled_temperature );
1820 }
1821
1822 // For an unmutated human swimming in deep water, this will add up to:
1823 // +26 when hot in 100% water friendly clothing
1824 // -52 when cold/hot in 100% unfriendly clothing
1825 total_morale += static_cast<int>( bp_morale * ( 1.0 + scaled_temperature ) / 4.0 );
1826 }
1827
1828 if( total_morale == 0 ) {
1829 return;
1830 }
1831
1832 int morale_effect = total_morale / 8;
1833 if( morale_effect == 0 ) {
1834 if( total_morale > 0 ) {
1835 morale_effect = 1;
1836 } else {
1837 morale_effect = -1;
1838 }
1839 }
1840 // 61_seconds because decay is applied in 1_minutes increments
1841 add_morale( MORALE_WET, morale_effect, total_morale, 61_seconds, 61_seconds, true );
1842}
constexpr std::array< body_part, 12 > all_body_parts
Contains all valid body_part values in the order they are defined in.
Definition: bodypart.h:84
body_part
Definition: bodypart.h:41
body_part_set exclusive_flag_coverage(const std::string &flag) const
Bitset of all the body parts covered only with items with flag (or nothing)
Definition: character.cpp:4069
std::array< std::array< int, NUM_WATER_TOLERANCE >, num_bp > mut_drench
Definition: character.h:858
const morale_type MORALE_WET("morale_wet")
quantity< V, U > fabs(quantity< V, U > q)
Definition: units_def.h:136
quantity< int, temperature_in_millidegree_celsius_tag > temperature
static constexpr int BODYTEMP_COLD
Do not change this value, it is an arbitrary anchor on which other calculations are made.
Definition: weather.h:34
static constexpr int BODYTEMP_HOT
Level 2 hotness.
Definition: weather.h:38

References add_morale(), all_body_parts, body_wetness, BODYTEMP_COLD, BODYTEMP_HOT, exclusive_flag_coverage(), units::fabs(), MORALE_WET, mut_drench, temp_cur, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by game::do_turn().

◆ armor_absorb()

bool Character::armor_absorb ( damage_unit du,
item armor 
)

Reduces and mutates du, prints messages about armor taking damage.

Returns
true if the armor was completely destroyed (and the item must be deleted).

Definition at line 8165 of file character.cpp.

8166{
8167 if( rng( 1, 100 ) > armor.get_coverage() ) {
8168 return false;
8169 }
8170
8171 // TODO: add some check for power armor
8172 armor.mitigate_damage( du );
8173
8174 // We want armor's own resistance to this type, not the resistance it grants
8175 const int armors_own_resist = armor.damage_resist( du.type, true );
8176 if( armors_own_resist > 1000 ) {
8177 // This is some weird type that doesn't damage armors
8178 return false;
8179 }
8180
8181 // Scale chance of article taking damage based on the number of parts it covers.
8182 // This represents large articles being able to take more punishment
8183 // before becoming ineffective or being destroyed.
8184 const int num_parts_covered = armor.get_covered_body_parts().count();
8185 if( !one_in( num_parts_covered ) ) {
8186 return false;
8187 }
8188
8189 // Don't damage armor as much when bypassed by armor piercing
8190 // Most armor piercing damage comes from bypassing armor, not forcing through
8191 const int raw_dmg = du.amount * std::min( 1.0f, du.damage_multiplier );
8192 if( raw_dmg > armors_own_resist ) {
8193 // If damage is above armor value, the chance to avoid armor damage is
8194 // 50% + 50% * 1/dmg
8195 if( one_in( raw_dmg ) || one_in( 2 ) ) {
8196 return false;
8197 }
8198 } else {
8199 // Sturdy items and power armors never take chip damage.
8200 // Other armors have 0.5% of getting damaged from hits below their armor value.
8201 if( armor.has_flag( flag_STURDY ) || !one_in( 200 ) ) {
8202 return false;
8203 }
8204 }
8205
8206 const material_type &material = armor.get_random_material();
8207 std::string damage_verb = ( du.type == DT_BASH ) ? material.bash_dmg_verb() :
8208 material.cut_dmg_verb();
8209
8210 const std::string pre_damage_name = armor.tname();
8211 const std::string pre_damage_adj = armor.get_base_material().dmg_adj( armor.damage_level( 4 ) );
8212
8213 // add "further" if the damage adjective and verb are the same
8214 std::string format_string = ( pre_damage_adj == damage_verb ) ?
8215 _( "Your %1$s is %2$s further!" ) : _( "Your %1$s is %2$s!" );
8216 add_msg_if_player( m_bad, format_string, pre_damage_name, damage_verb );
8217 //item is damaged
8218 if( is_player() ) {
8219 SCT.add( point( posx(), posy() ), direction::NORTH, remove_color_tags( pre_damage_name ), m_neutral,
8220 damage_verb,
8221 m_info );
8222 }
8223
8224 return armor.mod_damage( armor.has_flag( "FRAGILE" ) ?
8226}
static const std::string flag_STURDY("STURDY")
size_t count() const
Definition: bodypart.h:271
const material_type & get_random_material() const
Get a material reference to a random material that this item is made of.
Definition: item.cpp:7156
bool mod_damage(int qty, damage_type dt)
Apply damage to const itemrained by min_damage and max_damage.
Definition: item.cpp:6236
int damage_level(int max) const
Scale item damage to the given number of levels.
Definition: item.cpp:706
int damage_resist(damage_type dt, bool to_self=false) const
Resistance provided by this item against damage type given by an enum.
Definition: item.cpp:6381
const material_type & get_base_material() const
Get the basic (main) material of this item.
Definition: item.cpp:7161
body_part_set get_covered_body_parts() const
Bitset of all covered body parts.
Definition: item.cpp:758
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5910
void mitigate_damage(damage_unit &du) const
Assuming that specified du hit the armor, reduce du based on the item's resistance to the damage type...
Definition: item.cpp:6373
std::string cut_dmg_verb() const
Definition: material.cpp:190
std::string dmg_adj(int damage) const
Definition: material.cpp:195
std::string bash_dmg_verb() const
Definition: material.cpp:185
float damage_multiplier
Definition: damage.h:40
static constexpr int damage_scale
Definition: itype.h:979

References _, scrollingcombattext::add(), Creature::add_msg_if_player(), damage_unit::amount, material_type::bash_dmg_verb(), body_part_set::count(), material_type::cut_dmg_verb(), item::damage_level(), damage_unit::damage_multiplier, item::damage_resist(), itype::damage_scale, material_type::dmg_adj(), DT_BASH, flag_STURDY(), item::get_base_material(), item::get_coverage(), item::get_covered_body_parts(), item::get_random_material(), item::has_flag(), Creature::is_player(), m_bad, m_info, m_neutral, item::mitigate_damage(), item::mod_damage(), NORTH, one_in(), posx(), posy(), remove_color_tags(), rng(), SCT, item::tname(), and damage_unit::type.

Referenced by absorb_hit().

◆ armwear_factor()

double Character::armwear_factor ( ) const

Same as footwear factor, but for arms.

Definition at line 8930 of file character.cpp.

8931{
8932 double ret = 0;
8933 if( wearing_something_on( bodypart_id( "arm_l" ) ) ) {
8934 ret += .5;
8935 }
8936 if( wearing_something_on( bodypart_id( "arm_r" ) ) ) {
8937 ret += .5;
8938 }
8939 return ret;
8940}
bool wearing_something_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body part.
Definition: character.cpp:8866

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by suffer_in_sunlight().

◆ as_character() [1/2]

const Character * Character::as_character ( ) const
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 235 of file character.h.

235 {
236 return this;
237 }

◆ as_character() [2/2]

Character * Character::as_character ( )
inlineoverridevirtual

Reimplemented from Creature.

Definition at line 232 of file character.h.

232 {
233 return this;
234 }

Referenced by debug_menu::character_edit_menu(), doors::close_door(), and emit_radio_signal().

◆ assign_activity() [1/2]

void Character::assign_activity ( const activity_id type,
int  moves = calendar::INDEFINITELY_LONG,
int  index = -1,
int  pos = INT_MIN,
const std::string &  name = "" 
)

Legacy activity assignment, does not work for any activites using the new activity_actor class and may cause issues with resuming.

TODO: delete this once migration of activites to the activity_actor system is complete

Definition at line 9196 of file character.cpp.

9198{
9200}
int moves
Definition: creature.h:582

References assign_activity(), Creature::moves, name, pos(), and type.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), butcher_submenu(), cast_spell(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), iuse::dig(), iuse::dig_channel(), crafting::disassemble_all(), overmap_ui::display(), talk_function::do_butcher(), talk_function::do_chop_plank(), talk_function::do_chop_trees(), talk_function::do_construction(), talk_function::do_farming(), talk_function::do_fishing(), talk_function::do_mining(), npc::do_pulp(), player_activity::do_turn(), talk_function::do_vehicle_deconstruct(), talk_function::do_vehicle_repair(), drop(), game::exam_vehicle(), iuse::fill_pit(), npc::find_job_to_perform(), talk_function::find_mount(), aim_activity_actor::finish(), avatar_action::fire_ranged_bionic(), avatar_action::fire_ranged_mutation(), avatar_action::fire_wielded_weapon(), activity_handlers::fish_finish(), iuse::fishing_rod(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), iuse::hand_crank(), install_bionics(), vehicle::interact_with(), iuse::jackhammer(), loot(), iuse::makemound(), iuse::meditate(), monexamine::milk_source(), iuse::mind_splicer(), mine_activity(), iuse::oxytorch(), iuse::pickaxe(), game::place_player(), iexamine::plant_seed(), iuse::play_game(), monexamine::play_with(), avatar_action::plthrow(), iuse::portable_game(), prompt_disassemble_single(), avatar::read(), avatar_action::reload(), activity_handlers::resume_for_multi_activities(), iuse::robotcontrol(), iexamine::rubble(), iexamine::safe(), iuse::shavekit(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), talk_function::sort_loot(), player::start_craft(), start_destination_activity(), game::start_hauling(), npc::start_read(), gates::toggle_gate(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), avatar_funcs::try_to_sleep(), uninstall_bionic(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), learn_spell_actor::use(), cast_spell_actor::use(), vehicle_activity(), iuse::vibe(), wait(), and wash_items().

◆ assign_activity() [2/2]

void Character::assign_activity ( const player_activity act,
bool  allow_resume = true 
)

Assigns activity to player, possibly resuming old activity if it's similar enough.

Definition at line 9202 of file character.cpp.

9203{
9204 bool resuming = false;
9205 if( allow_resume && !backlog.empty() && backlog.front().can_resume_with( act, *this ) ) {
9206 resuming = true;
9207 add_msg_if_player( _( "You resume your task." ) );
9208 activity = backlog.front();
9209 backlog.pop_front();
9210 } else {
9211 if( activity ) {
9212 backlog.push_front( activity );
9213 }
9214
9215 activity = act;
9216 }
9217
9218 activity.start_or_resume( *this, resuming );
9219
9220 if( is_npc() ) {
9222 npc *guy = dynamic_cast<npc *>( this );
9226 }
9227}
void cancel_stashed_activity()
Definition: character.cpp:902
std::list< player_activity > backlog
Definition: character.h:1577
Definition: npc.h:744
void set_attitude(npc_attitude new_attitude)
Definition: npc.cpp:3168
activity_id current_activity_id
Definition: npc.h:1212
void set_mission(npc_mission new_mission)
Definition: npc.cpp:3147
const activity_id & id() const
void start_or_resume(Character &who, bool resuming)
Preform necessary initialization to start or resume the activity.
@ NPCATT_ACTIVITY
Definition: npc.h:98
@ NPC_MISSION_ACTIVITY
Definition: npc.h:153
activity_id act
Definition: sounds.cpp:76

References _, act, activity, Creature::add_msg_if_player(), backlog, cancel_stashed_activity(), npc::current_activity_id, player_activity::id(), Creature::is_npc(), NPC_MISSION_ACTIVITY, NPCATT_ACTIVITY, npc::set_attitude(), npc::set_mission(), and player_activity::start_or_resume().

◆ assign_stashed_activity()

void Character::assign_stashed_activity ( )

Definition at line 924 of file character.cpp.

925{
929}
player_activity stashed_outbounds_backlog
Definition: character.h:1575
player_activity stashed_outbounds_activity
Definition: character.h:1574

References activity, backlog, cancel_stashed_activity(), stashed_outbounds_activity, and stashed_outbounds_backlog.

Referenced by npc::move().

◆ attack_cost()

int Character::attack_cost ( const item weap) const

Returns cost (in moves) of attacking with given item (no modifiers, like stuck)

Melee increases melee attack speed Dexterity increases attack speed

Definition at line 2279 of file melee.cpp.

2280{
2281 const int base_move_cost = weap.attack_cost() / 2;
2282 const int melee_skill = has_active_bionic( bionic_id( bio_cqb ) ) ? BIO_CQB_LEVEL : get_skill_level(
2283 skill_melee );
2284 /** @EFFECT_MELEE increases melee attack speed */
2285 const int skill_cost = static_cast<int>( ( base_move_cost * ( 15 - melee_skill ) / 15 ) );
2286 /** @EFFECT_DEX increases attack speed */
2287 const int dexbonus = dex_cur;
2288 const int encumbrance_penalty = encumb( bp_torso ) +
2289 ( encumb( bp_hand_l ) + encumb( bp_hand_r ) ) / 2;
2290 const int ma_move_cost = mabuff_attack_cost_penalty();
2291 const float stamina_ratio = static_cast<float>( get_stamina() ) / static_cast<float>
2292 ( get_stamina_max() );
2293 // Increase cost multiplier linearly from 1.0 to 2.0 as stamina goes from 25% to 0%.
2294 const float stamina_penalty = 1.0 + std::max( ( 0.25f - stamina_ratio ) * 4.0f, 0.0f );
2295 const float ma_mult = mabuff_attack_cost_mult();
2296
2297 int move_cost = base_move_cost;
2298 // Stamina penalty only affects base/2 and encumbrance parts of the cost
2299 move_cost += encumbrance_penalty;
2300 move_cost *= stamina_penalty;
2301 move_cost += skill_cost;
2302 move_cost -= dexbonus;
2303
2305
2306 // Martial arts last. Flat has to be after mult, because comments say so.
2307 move_cost *= ma_mult;
2308 move_cost += ma_move_cost;
2309
2310 move_cost *= mutation_value( "attackcost_modifier" );
2311
2312 if( move_cost < 25 ) {
2313 return 25;
2314 }
2315
2316 return move_cost;
2317}
static int move_cost(const item &it, const tripoint &src, const tripoint &dest)
int get_stamina() const
Definition: character.cpp:7093
float mabuff_attack_cost_mult() const
Returns the multiplier on move cost of attacks.
float mutation_value(const std::string &val) const
Goes over all mutations, gets min and max of a value with given name.
Definition: character.cpp:6650
int mabuff_attack_cost_penalty() const
Returns the flat penalty to move cost of attacks.
int encumb(body_part bp) const
Returns ENC provided by armor, etc.
Definition: character.cpp:4026
double bonus_from_enchantments(double base, enchant_vals::mod value, bool round=false) const
Calculate bonus from enchantments for given base value.
Definition: character.cpp:7915
int get_stamina_max() const
Definition: character.cpp:7098
int attack_cost() const
Base number of moves (Creature::moves) that a single melee attack with this items takes.
Definition: item.cpp:5208
static constexpr int BIO_CQB_LEVEL
static const bionic_id bio_cqb("bio_cqb")
static const skill_id skill_melee("melee")

References item::attack_cost(), enchant_vals::ATTACK_COST, bio_cqb, BIO_CQB_LEVEL, bionic_id, bonus_from_enchantments(), bp_hand_l, bp_hand_r, bp_torso, dex_cur, encumb(), get_skill_level(), get_stamina(), get_stamina_max(), has_active_bionic(), mabuff_attack_cost_mult(), mabuff_attack_cost_penalty(), move_cost(), mutation_value(), and skill_melee.

Referenced by item::combat_info(), item::effective_dps(), melee_attack(), reach_attack(), and avatar_funcs::try_disarm_npc().

◆ attitude_to()

Creature::Attitude Character::attitude_to ( const Creature other) const
overridevirtual

Attitude (of this creature) towards another creature.

This might not be symmetric.

Implements Creature.

Reimplemented in npc.

Definition at line 10394 of file character.cpp.

10395{
10396 const auto m = dynamic_cast<const monster *>( &other );
10397 if( m != nullptr ) {
10398 if( m->friendly != 0 ) {
10399 return A_FRIENDLY;
10400 }
10401 switch( m->attitude( const_cast<Character *>( this ) ) ) {
10402 // player probably does not want to harm them, but doesn't care much at all.
10403 case MATT_FOLLOW:
10404 case MATT_FPASSIVE:
10405 case MATT_IGNORE:
10406 case MATT_FLEE:
10407 return A_NEUTRAL;
10408 // player does not want to harm those.
10409 case MATT_FRIEND:
10410 case MATT_ZLAVE:
10411 // Don't want to harm your zlave!
10412 return A_FRIENDLY;
10413 case MATT_ATTACK:
10414 return A_HOSTILE;
10415 case MATT_NULL:
10417 break;
10418 }
10419
10420 return A_NEUTRAL;
10421 }
10422
10423 const auto p = dynamic_cast<const npc *>( &other );
10424 if( p != nullptr ) {
10425 if( p->is_enemy() ) {
10426 return A_HOSTILE;
10427 } else if( p->is_player_ally() ) {
10428 return A_FRIENDLY;
10429 } else {
10430 return A_NEUTRAL;
10431 }
10432 } else if( &other == this ) {
10433 return A_FRIENDLY;
10434 }
10435
10436 return A_NEUTRAL;
10437}
@ A_NEUTRAL
Definition: creature.h:168
@ A_HOSTILE
Definition: creature.h:167
@ A_FRIENDLY
Definition: creature.h:169
@ MATT_ZLAVE
Definition: monster.h:63
@ MATT_FLEE
Definition: monster.h:59
@ NUM_MONSTER_ATTITUDES
Definition: monster.h:64
@ MATT_FRIEND
Definition: monster.h:57
@ MATT_FOLLOW
Definition: monster.h:61
@ MATT_ATTACK
Definition: monster.h:62
@ MATT_NULL
Definition: monster.h:56
@ MATT_IGNORE
Definition: monster.h:60
@ MATT_FPASSIVE
Definition: monster.h:58

References Creature::A_FRIENDLY, Creature::A_HOSTILE, Creature::A_NEUTRAL, MATT_ATTACK, MATT_FLEE, MATT_FOLLOW, MATT_FPASSIVE, MATT_FRIEND, MATT_IGNORE, MATT_NULL, MATT_ZLAVE, NUM_MONSTER_ATTITUDES, and other.

Referenced by game::is_hostile_within(), and show_armor_layers_ui().

◆ avoid_trap()

bool Character::avoid_trap ( const tripoint pos,
const trap tr 
) const
overridevirtual

Called when character triggers a trap, returns true if they don't set it off.

Dexterity increases chance to avoid traps Dodge increases chance to avoid traps

Implements Creature.

Definition at line 10270 of file character.cpp.

10271{
10272 /** @EFFECT_DEX increases chance to avoid traps */
10273
10274 /** @EFFECT_DODGE increases chance to avoid traps */
10275 int myroll = dice( 3, dex_cur + get_skill_level( skill_dodge ) * 1.5 );
10276 int traproll;
10277 if( tr.can_see( pos, *this ) ) {
10278 traproll = dice( 3, tr.get_avoidance() );
10279 } else {
10280 traproll = dice( 6, tr.get_avoidance() );
10281 }
10282
10283 return myroll >= traproll;
10284}
static const skill_id skill_dodge("dodge")
int dice(int number, int sides)
Definition: rng.cpp:85
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References trap::can_see(), dex_cur, dice(), trap::get_avoidance(), get_skill_level(), pos(), and skill_dodge.

◆ base_age()

int Character::base_age ( ) const

Definition at line 6785 of file character.cpp.

6786{
6787 return init_age;
6788}

References init_age.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_age(), and set_description().

◆ base_height()

int Character::base_height ( ) const

Definition at line 6814 of file character.cpp.

6815{
6816 return init_height;
6817}
int init_height
height at character creation
Definition: character.h:2140

References init_height.

Referenced by debug_menu::character_edit_menu(), char_creation::draw_height(), and set_description().

◆ basic_symbol_color()

nc_color Character::basic_symbol_color ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 6018 of file character.cpp.

6019{
6020 if( has_effect( effect_onfire ) ) {
6021 return c_red;
6022 }
6023 if( has_effect( effect_stunned ) ) {
6024 return c_light_blue;
6025 }
6026 if( has_effect( effect_boomered ) ) {
6027 return c_pink;
6028 }
6029 if( has_active_mutation( trait_id( "SHELL2" ) ) ) {
6030 return c_magenta;
6031 }
6032 if( is_underwater() ) {
6033 return c_blue;
6034 }
6037 return c_dark_gray;
6038 }
6039 if( move_mode == CMM_RUN ) {
6040 return c_yellow;
6041 }
6042 if( move_mode == CMM_CROUCH ) {
6043 return c_light_gray;
6044 }
6045 return c_white;
6046}
static const trait_id trait_DEBUG_CLOAK("DEBUG_CLOAK")
static const efftype_id effect_boomered("boomered")
static const bionic_id bio_cloak("bio_cloak")
static const efftype_id effect_stunned("stunned")
@ CMM_RUN
Definition: character.h:110
@ CMM_CROUCH
Definition: character.h:111
bool has_active_mutation(const trait_id &b) const
Definition: mutation.cpp:365
bool is_wearing_active_optcloak() const
Returns true if the player is wearing an active optical cloak.
Definition: character.cpp:3843
virtual bool is_underwater() const
Definition: creature.cpp:172
#define c_white
Definition: color.h:18
#define c_light_gray
Definition: color.h:19
#define c_blue
Definition: color.h:23
#define c_magenta
Definition: color.h:25
#define c_dark_gray
Definition: color.h:20
#define c_pink
Definition: color.h:31
#define c_light_blue
Definition: color.h:29
#define c_yellow
Definition: color.h:32
#define c_red
Definition: color.h:21
@ AEP_INVISIBLE
Definition: enums.h:110

References AEP_INVISIBLE, bio_cloak, c_blue, c_dark_gray, c_light_blue, c_light_gray, c_magenta, c_pink, c_red, c_white, c_yellow, CMM_CROUCH, CMM_RUN, effect_boomered, effect_onfire, effect_stunned, has_active_bionic(), has_active_mutation(), has_artifact_with(), Creature::has_effect(), has_trait(), Creature::is_underwater(), is_wearing_active_optcloak(), move_mode, trait_DEBUG_CLOAK, and trait_id.

Referenced by symbol_color().

◆ best_nearby_lifting_assist() [1/2]

int Character::best_nearby_lifting_assist ( ) const

Checks for items, tools, and vehicles with the Lifting quality near the character returning the highest quality in range.

Definition at line 2548 of file character.cpp.

2549{
2550 return best_nearby_lifting_assist( this->pos() );
2551}
int best_nearby_lifting_assist() const
Checks for items, tools, and vehicles with the Lifting quality near the character returning the highe...
Definition: character.cpp:2548

References best_nearby_lifting_assist(), and pos().

Referenced by best_nearby_lifting_assist(), veh_interact::cache_tool_availability_update_lifting(), can_do_activity_there(), and weight_carried_reduced_by().

◆ best_nearby_lifting_assist() [2/2]

int Character::best_nearby_lifting_assist ( const tripoint world_pos) const

Alternate version if you need to specify a different orign point for nearby vehicle sources of lifting used for operations on distant objects (e.g.

vehicle installation/uninstallation)

Definition at line 2553 of file character.cpp.

2554{
2555 const quality_id LIFT( "LIFT" );
2556 int mech_lift = 0;
2557 if( is_mounted() ) {
2558 auto mons = mounted_creature.get();
2559 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
2560 mech_lift = mons->mech_str_addition() + 10;
2561 }
2562 }
2563 return std::max( { this->max_quality( LIFT ), mech_lift,
2564 map_selector( this->pos(), PICKUP_RANGE, false ).max_quality( LIFT ),
2565 vehicle_selector( world_pos, PICKUP_RANGE, false ).max_quality( LIFT )
2566 } );
2567}
int PICKUP_RANGE
Items on the map with at most this distance to the player are considered available for crafting,...
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1615
int max_quality(const quality_id &qual) const
Return maximum tool quality level provided by instance or INT_MIN if not found.
Definition: visitable.cpp:277
@ MF_RIDEABLE_MECH
Definition: mtype.h:116

References is_mounted(), visitable< T >::max_quality(), visitable< Character >::max_quality(), MF_RIDEABLE_MECH, mounted_creature, PICKUP_RANGE, and pos().

◆ best_quality_item()

item * Character::best_quality_item ( const quality_id qual)

get best quality item that this character has

Definition at line 4754 of file character.cpp.

4755{
4756 std::vector<item *> qual_inv = items_with( [qual]( const item & itm ) {
4757 return itm.has_quality( qual );
4758 } );
4759 item *best_qual = random_entry( qual_inv );
4760 for( const auto elem : qual_inv ) {
4761 if( elem->get_quality( qual ) > best_qual->get_quality( qual ) ) {
4762 best_qual = elem;
4763 }
4764 }
4765 return best_qual;
4766}
bool has_quality(const quality_id &qual, int level=1, int qty=1) const
Returns true if instance has amount (or more) items of at least quality level.
Definition: visitable.cpp:170
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References visitable< T >::has_quality(), visitable< Character >::items_with(), and random_entry().

Referenced by chop_plank_activity(), chop_tree_activity(), generic_multi_activity_do(), and monexamine::shear_animal().

◆ best_shield()

item & Character::best_shield ( )

Returns the best item for blocking with.

Definition at line 1603 of file melee.cpp.

1604{
1605 // Note: wielded weapon, not one used for attacks
1606 int best_value = blocking_ability( primary_weapon() );
1607 // "BLOCK_WHILE_WORN" without a blocking tech need to be worn for the bonus
1608 best_value = best_value == 2 ? 0 : best_value;
1609 item *best = best_value > 0 ? &primary_weapon() : &null_item_reference();
1610 for( item &shield : worn ) {
1611 if( shield.has_flag( "BLOCK_WHILE_WORN" ) && blocking_ability( shield ) >= best_value ) {
1612 // in case a mod adds a shield that protects only one arm, the corresponding arm needs to be working
1613 if( shield.covers( bp_arm_l ) || shield.covers( bp_arm_r ) ) {
1614 if( shield.covers( bp_arm_l ) && !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1615 best = &shield;
1616 } else if( shield.covers( bp_arm_r ) && !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1617 best = &shield;
1618 }
1619 // leg guards
1620 } else if( ( shield.covers( bp_leg_l ) || shield.covers( bp_leg_r ) ) &&
1621 get_working_leg_count() >= 1 ) {
1622 best = &shield;
1623 // in case a mod adds an unusual worn blocking item, like a magic bracelet/crown, it's handled here
1624 } else {
1625 best = &shield;
1626 }
1627 }
1628 }
1629
1630 return *best;
1631}
int get_working_leg_count() const
Returns the number of functioning legs.
Definition: character.cpp:1245
bool is_limb_disabled(const bodypart_id &limb) const
Returns true if the limb is disabled (12.5% or less hp, or broken)
Definition: character.cpp:1257
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:327
static int blocking_ability(const item &shield)
Definition: melee.cpp:1588

References blocking_ability(), bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r, get_working_leg_count(), is_limb_disabled(), null_item_reference(), primary_weapon(), and worn.

Referenced by block_hit(), and block_ranged_hit().

◆ bionic_armor_bonus()

float Character::bionic_armor_bonus ( const bodypart_id bp,
damage_type  dt 
) const

Check for passive bionics that provide armor, and returns the armor bonus This is called from player::passive_absorb_hit.

Definition at line 8228 of file character.cpp.

8229{
8230 float result = 0.0f;
8231 if( dt == DT_CUT || dt == DT_STAB ) {
8232 for( const bionic_id &bid : get_bionics() ) {
8233 const auto cut_prot = bid->cut_protec.find( bp.id() );
8234 if( cut_prot != bid->cut_protec.end() ) {
8235 result += cut_prot->second;
8236 }
8237 }
8238 } else if( dt == DT_BASH ) {
8239 for( const bionic_id &bid : get_bionics() ) {
8240 const auto bash_prot = bid->bash_protec.find( bp.id() );
8241 if( bash_prot != bid->bash_protec.end() ) {
8242 result += bash_prot->second;
8243 }
8244 }
8245 } else if( dt == DT_BULLET ) {
8246 for( const bionic_id &bid : get_bionics() ) {
8247 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
8248 if( bullet_prot != bid->bullet_protec.end() ) {
8249 result += bullet_prot->second;
8250 }
8251 }
8252 }
8253
8254 return result;
8255}
std::vector< bionic_id > get_bionics() const
Definition: character.cpp:1795
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References bionic_data::bash_protec, bionic_data::bullet_protec, bionic_data::cut_protec, DT_BASH, DT_BULLET, DT_CUT, DT_STAB, get_bionics(), and int_id< T >::id().

Referenced by passive_absorb_hit().

◆ bionic_installation_issues()

std::map< bodypart_id, int > Character::bionic_installation_issues ( const bionic_id bioid) const

Definition at line 2555 of file bionics.cpp.

2556{
2557 std::map<bodypart_id, int> issues;
2558 if( !get_option < bool >( "CBM_SLOTS_ENABLED" ) ) {
2559 return issues;
2560 }
2561 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2562 const int lacked_slots = elem.second - get_free_bionics_slots( elem.first );
2563 if( lacked_slots > 0 ) {
2564 issues.emplace( elem.first, lacked_slots );
2565 }
2566 }
2567 return issues;
2568}
int get_free_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2575
std::map< bodypart_str_id, int > occupied_bodyparts
Body part slots used to install this bionic, mapped to the amount of space required.
Definition: bionics.h:95

References get_free_bionics_slots(), and bionic_data::occupied_bodyparts.

Referenced by can_install_bionics(), and item::color_in_inventory().

◆ bionics_adjusted_skill()

float Character::bionics_adjusted_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate skill for (un)installing bionics.

Definition at line 1898 of file bionics.cpp.

1902{
1903 int pl_skill = bionics_pl_skill( most_important_skill, important_skill, least_important_skill,
1904 skill_level );
1905
1906 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
1907 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
1908 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>( 10.0 ) );
1909 adjusted_skill *= env_surgery_bonus( 1 ) + get_effect_int( effect_assisted );
1910 return adjusted_skill;
1911}
static const efftype_id effect_assisted("assisted")
float env_surgery_bonus(int radius)
Calculate skill bonus from tiles in radius.
Definition: bionics.cpp:2287
int bionics_pl_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate non adjusted skill for (un)installing bionics.
Definition: bionics.cpp:1913
int get_effect_int(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the intensity of the matching effect.
Definition: creature.cpp:1291

References bionics_pl_skill(), effect_assisted, env_surgery_bonus(), and Creature::get_effect_int().

Referenced by best_installer(), can_install_bionics(), can_uninstall_bionic(), bionic_install_preset::get_failure_chance(), bionic_install_surgeon_preset::get_failure_chance(), bionic_uninstall_preset::get_failure_chance(), install_bionics(), game::save_cyborg(), and uninstall_bionic().

◆ bionics_install_failure()

void Character::bionics_install_failure ( const std::string &  installer,
int  difficulty,
int  success,
float  adjusted_skill 
)

Definition at line 2448 of file bionics.cpp.

2450{
2451 // "success" should be passed in as a negative integer representing how far off we
2452 // were for a successful install. We use this to determine consequences for failing.
2453 success = std::abs( success );
2454
2455 // failure level is decided by how far off the character was from a successful install, and
2456 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
2457 // difficulties), only minor consequences occur. At low skill levels, severe consequences
2458 // are more likely.
2459 int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty / adjusted_skill ) );
2460 int fail_type = ( failure_level > 5 ? 5 : failure_level );
2461
2462 if( installer != "NOT_MED" ) {
2463 //~"Complications" is USian medical-speak for "unintended damage from a medical procedure".
2464 add_msg( m_neutral, _( "%s training helps to minimize the complications." ),
2465 installer );
2466 // In addition to the bonus, medical residents know enough OR protocol to avoid botching.
2467 // Take MD and be immune to faulty bionics.
2468 if( fail_type > 3 ) {
2469 fail_type = rng( 1, 3 );
2470 }
2471 }
2472
2473 switch( fail_type ) {
2474 case 0:
2475 case 1:
2477 break;
2478 case 2:
2479 case 3:
2480 do_damage_for_bionic_failure( 5, difficulty * 5 );
2481 break;
2482 case 4:
2483 case 5: {
2484 std::vector<bionic_id> valid;
2485 std::copy_if( begin( faulty_bionics ), end( faulty_bionics ), std::back_inserter( valid ),
2486 [&]( const bionic_id & id ) {
2487 return !has_bionic( id );
2488 } );
2489
2490 // We've got all the bad bionics!
2491 if( valid.empty() ) {
2492 if( has_max_power() ) {
2493 units::energy old_power = get_max_power_level();
2494 add_msg( m_bad, _( "%s lose power capacity!" ), disp_name() );
2499 }
2500 if( is_player() ) {
2501 g->memorial().add(
2502 pgettext( "memorial_male", "Lost %d units of power capacity." ),
2503 pgettext( "memorial_female", "Lost %d units of power capacity." ),
2504 units::to_kilojoule( old_power - get_max_power_level() ) );
2505 }
2506 // If no faults available and no power capacity, downgrade to second-worst complication.
2507 } else {
2508 do_damage_for_bionic_failure( 5, difficulty * 5 );
2509 break;
2510 }
2511 } else {
2512 const bionic_id &id = random_entry( valid );
2513 add_bionic( id );
2514 g->events().send<event_type::installs_faulty_cbm>( getID(), id );
2515 add_msg( m_bad,
2516 _( "Complication in installation caused a malfunction - %s. Uninstall it to clear the malfunction." ),
2517 id.obj().name );
2518 }
2519 }
2520 break;
2521 }
2522
2523}
bool has_max_power() const
Definition: character.cpp:1952
void set_max_power_level(const units::energy &npower_max)
Definition: character.cpp:1920
void do_damage_for_bionic_failure(int min_damage, int max_damage)
Definition: bionics.cpp:2408
@ installs_faulty_cbm
std::vector< bionic_id > faulty_bionics
Definition: bionics.cpp:216
const char * pgettext(const char *context, const char *msgid)

References _, add_bionic(), add_msg(), disp_name(), do_damage_for_bionic_failure(), anonymous_namespace{bionics.cpp}::faulty_bionics, units::from_kilojoule(), g, get_max_power_level(), getID(), has_bionic(), has_max_power(), id, installs_faulty_cbm, Creature::is_player(), m_bad, m_neutral, name, pgettext(), random_entry(), rng(), set_max_power_level(), behavior::success, and units::to_kilojoule().

Referenced by perform_install().

◆ bionics_pl_skill()

int Character::bionics_pl_skill ( const skill_id most_important_skill,
const skill_id important_skill,
const skill_id least_important_skill,
int  skill_level = -1 
)

Calculate non adjusted skill for (un)installing bionics.

Definition at line 1913 of file bionics.cpp.

1916{
1917 int pl_skill;
1918 if( skill_level == -1 ) {
1919 pl_skill = int_cur * 4 +
1920 get_skill_level( most_important_skill ) * 4 +
1921 get_skill_level( important_skill ) * 3 +
1922 get_skill_level( least_important_skill ) * 1;
1923 } else {
1924 // override chance as though all values were skill_level if it is provided
1925 pl_skill = 12 * skill_level;
1926 }
1927
1928 // Medical residents have some idea what they're doing
1929 if( has_trait( trait_PROF_MED ) ) {
1930 pl_skill += 3;
1931 }
1932
1933 // People trained in bionics gain an additional advantage towards using it
1934 if( has_trait( trait_PROF_AUTODOC ) ) {
1935 pl_skill += 7;
1936 }
1937 return pl_skill;
1938}
static const trait_id trait_PROF_MED("PROF_MED")
static const trait_id trait_PROF_AUTODOC("PROF_AUTODOC")

References get_skill_level(), has_trait(), int_cur, trait_PROF_AUTODOC, and trait_PROF_MED.

Referenced by bionics_adjusted_skill(), install_bionics(), and uninstall_bionic().

◆ bionics_uninstall_failure() [1/2]

void Character::bionics_uninstall_failure ( int  difficulty,
int  success,
float  adjusted_skill 
)

When a player fails the surgery.

Definition at line 1789 of file bionics.cpp.

1790{
1791 // "success" should be passed in as a negative integer representing how far off we
1792 // were for a successful removal. We use this to determine consequences for failing.
1793 success = std::abs( success );
1794
1795 // failure level is decided by how far off the character was from a successful removal, and
1796 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1797 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1798 // are more likely.
1799 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1800 adjusted_skill ) );
1801 const int fail_type = std::min( 5, failure_level );
1802
1803 if( fail_type <= 1 ) {
1804 add_msg( m_neutral, _( "The removal fails without incident." ) );
1805 return;
1806 }
1807
1808 add_msg( m_neutral, _( "The removal is a failure." ) );
1809 std::set<body_part> bp_hurt;
1810 switch( fail_type ) {
1811 case 2:
1812 case 3:
1814 break;
1815
1816 case 4:
1817 case 5:
1818 do_damage_for_bionic_failure( 5, difficulty * 5 );
1819 break;
1820 }
1821
1822}

References _, add_msg(), do_damage_for_bionic_failure(), m_neutral, and behavior::success.

Referenced by perform_uninstall(), and uninstall_bionic().

◆ bionics_uninstall_failure() [2/2]

void Character::bionics_uninstall_failure ( monster installer,
player patient,
int  difficulty,
int  success,
float  adjusted_skill 
)

When a monster fails the surgery.

Definition at line 1824 of file bionics.cpp.

1826{
1827
1828 // "success" should be passed in as a negative integer representing how far off we
1829 // were for a successful removal. We use this to determine consequences for failing.
1830 success = std::abs( success );
1831
1832 // failure level is decided by how far off the monster was from a successful removal, and
1833 // this is scaled up or down by the ratio of difficulty/skill. At high skill levels (or low
1834 // difficulties), only minor consequences occur. At low skill levels, severe consequences
1835 // are more likely.
1836 const int failure_level = static_cast<int>( std::sqrt( success * 4.0 * difficulty /
1837 adjusted_skill ) );
1838 const int fail_type = std::min( 5, failure_level );
1839
1840 bool u_see = sees( patient );
1841
1842 if( u_see || patient.is_player() ) {
1843 if( fail_type <= 1 ) {
1844 add_msg( m_neutral, _( "The removal fails without incident." ) );
1845 return;
1846 }
1847 switch( rng( 1, 5 ) ) {
1848 case 1:
1849 add_msg( m_mixed, _( "The %s flub the operation." ), installer.name() );
1850 break;
1851 case 2:
1852 add_msg( m_mixed, _( "The %s messes up the operation." ), installer.name() );
1853 break;
1854 case 3:
1855 add_msg( m_mixed, _( "The operation fails." ) );
1856 break;
1857 case 4:
1858 add_msg( m_mixed, _( "The operation is a failure." ) );
1859 break;
1860 case 5:
1861 add_msg( m_mixed, _( "The %s screws up the operation." ), installer.name() );
1862 break;
1863 }
1864 }
1865 switch( fail_type ) {
1866 case 2:
1867 case 3:
1868 do_damage_for_bionic_failure( failure_level, failure_level * 2 );
1869 break;
1870
1871 case 4:
1872 case 5:
1873 do_damage_for_bionic_failure( 5, difficulty * 5 );
1874 break;
1875 }
1876}
std::string name(unsigned int quantity=1) const
Definition: monster.cpp:489
bool is_player() const override
Definition: player.h:93

References _, add_msg(), do_damage_for_bionic_failure(), player::is_player(), m_mixed, m_neutral, monster::name(), rng(), sees(), and behavior::success.

◆ bionics_weight()

units::mass Character::bionics_weight ( ) const

Definition at line 6768 of file character.cpp.

6769{
6770 units::mass bio_weight = 0_gram;
6771 for( const bionic_id &bid : get_bionics() ) {
6772 if( !bid->included ) {
6773 bio_weight += bid->itype()->weight;
6774 }
6775 }
6776 return bio_weight;
6777}

References get_bionics().

Referenced by get_weight().

◆ block_hit()

bool Character::block_hit ( Creature source,
bodypart_id bp_hit,
damage_instance dam 
)
overridevirtual

Checks for valid block abilities and reduces damage accordingly.

Returns true if the player blocks

Strength increases attack blocking effectiveness with a limb or worn/wielded item Unarmed increases attack blocking effectiveness with a limb or worn/wielded item

Implements Creature.

Definition at line 1633 of file melee.cpp.

1634{
1635 // Shouldn't block if player is asleep
1637 return false;
1638 }
1639
1640 // fire martial arts on-getting-hit-triggered effects
1641 // these fire even if the attack is blocked (you still got hit)
1642 martial_arts_data->ma_ongethit_effects( *this );
1643
1644 if( blocks_left < 1 ) {
1645 return false;
1646 }
1647
1648 blocks_left--;
1649
1650 // This bonus absorbs damage from incoming attacks before they land,
1651 // but it still counts as a block even if it absorbs all the damage.
1652 float total_phys_block = mabuff_block_bonus();
1653
1654 // Extract this to make it easier to implement shields/multiwield later
1655 item &shield = best_shield();
1656 block_bonus = blocking_ability( shield );
1657 bool conductive_shield = shield.conductive();
1658 bool unarmed = primary_weapon().has_flag( "UNARMED_WEAPON" ) || primary_weapon().is_null();
1659 bool force_unarmed = martial_arts_data->is_force_unarmed();
1660
1661 int melee_skill = get_skill_level( skill_melee );
1662 int unarmed_skill = get_skill_level( skill_unarmed );
1663
1664 // Check if we are going to block with an item. This could
1665 // be worn equipment with the BLOCK_WHILE_WORN flag.
1666 const bool has_shield = !shield.is_null();
1667
1668 // boolean check if blocking is being done with unarmed or not
1669 const bool item_blocking = !force_unarmed && has_shield && !unarmed;
1670
1671 int block_score = 1;
1672
1673 /** @EFFECT_STR increases attack blocking effectiveness with a limb or worn/wielded item */
1674 /** @EFFECT_UNARMED increases attack blocking effectiveness with a limb or worn/wielded item */
1675 if( ( unarmed || force_unarmed ) ) {
1676 if( martial_arts_data->can_limb_block( *this ) ) {
1677 // block_bonus for limb blocks will be added when the limb is decided
1678 block_score = str_cur + melee_skill + unarmed_skill;
1679 } else if( has_shield ) {
1680 // We can still block with a worn item while unarmed. Use higher of melee and unarmed
1681 block_score = str_cur + block_bonus + std::max( melee_skill, unarmed_skill );
1682 }
1683 } else if( has_shield ) {
1684 block_score = str_cur + block_bonus + get_skill_level( skill_melee );
1685 } else {
1686 // Can't block with limbs or items (do not block)
1687 return false;
1688 }
1689
1690 // weapon blocks are preferred to limb blocks
1691 std::string thing_blocked_with;
1692 if( !force_unarmed && has_shield ) {
1693 thing_blocked_with = shield.tname();
1694 // TODO: Change this depending on damage blocked
1695 float wear_modifier = 1.0f;
1696 if( source != nullptr && source->is_hallucination() ) {
1697 wear_modifier = 0.0f;
1698 }
1699
1700 handle_melee_wear( shield, wear_modifier );
1701 } else {
1702 std::vector<bodypart_id> block_parts;
1703 if( martial_arts_data->can_leg_block( *this ) ) {
1704 block_parts.emplace_back( bodypart_id( "leg_l" ) );
1705 block_parts.emplace_back( bodypart_id( "leg_r" ) );
1706 }
1707 // If you have no martial arts you can still try to block with your arms.
1708 // But martial arts with leg blocks only don't magically get arm blocks.
1709 // Edge case: Leg block only martial arts gain arm blocks if both legs broken.
1710 if( martial_arts_data->can_arm_block( *this ) || block_parts.empty() ) {
1711 block_parts.emplace_back( bodypart_id( "arm_l" ) );
1712 block_parts.emplace_back( bodypart_id( "arm_r" ) );
1713 }
1714 block_parts.erase( std::remove_if( block_parts.begin(),
1715 block_parts.end(), [this]( bodypart_id & bpid ) {
1716 return get_part_hp_cur( bpid ) <= 0;
1717 } ), block_parts.end() );
1718
1719 const auto part_hp_cmp = [this]( const bodypart_id & lhs, const bodypart_id & rhs ) {
1720 return get_part_hp_cur( lhs ) < get_part_hp_cur( rhs );
1721 };
1722 auto healthiest = std::max_element( block_parts.begin(), block_parts.end(), part_hp_cmp );
1723 if( healthiest == block_parts.end() ) {
1724 // We have no parts with HP to block with.
1725 blocks_left = 0;
1726 return false;
1727 }
1728 bp_hit = *healthiest;
1729
1730 thing_blocked_with = body_part_name( bp_hit->token );
1731 }
1732
1733 if( has_shield ) {
1734 // Does our shield cover the limb we blocked with? If so, add the block bonus.
1735 block_score += shield.covers( bp_hit->token ) ? block_bonus : 0;
1736 }
1737
1738 // Map block_score to the logistic curve for a number between 1 and 0.
1739 // Basic beginner character (str 8, skill 0, basic weapon)
1740 // Will have a score around 10 and block about %15 of incoming damage.
1741 // More proficient melee character (str 10, skill 4, wbock_2 weapon)
1742 // will have a score of 20 and block about 45% of damage.
1743 // A highly expert character (str 14, skill 8 wblock_2)
1744 // will have a score in the high 20s and will block about 80% of damage.
1745 // As the block score approaches 40, damage making it through will dwindle
1746 // to nothing, at which point we're relying on attackers hitting enough to drain blocks.
1747 const float physical_block_multiplier = logarithmic_range( 0, 40, block_score );
1748
1749 float total_damage = 0.0;
1750 float damage_blocked = 0.0;
1751
1752 for( auto &elem : dam.damage_units ) {
1753 total_damage += elem.amount;
1754
1755 // block physical damage "normally"
1756 if( elem.type == DT_BASH || elem.type == DT_CUT || elem.type == DT_STAB ) {
1757 // use up our flat block bonus first
1758 float block_amount = std::min( total_phys_block, elem.amount );
1759 total_phys_block -= block_amount;
1760 elem.amount -= block_amount;
1761 damage_blocked += block_amount;
1762
1763 if( elem.amount <= std::numeric_limits<float>::epsilon() ) {
1764 continue;
1765 }
1766
1767 float previous_amount = elem.amount;
1768 elem.amount *= physical_block_multiplier;
1769 damage_blocked += previous_amount - elem.amount;
1770 }
1771
1772 // non-electrical "elemental" damage types do their full damage if unarmed,
1773 // but severely mitigated damage if not
1774 else if( elem.type == DT_HEAT || elem.type == DT_ACID || elem.type == DT_COLD ) {
1775 // Unarmed weapons won't block those
1776 if( item_blocking ) {
1777 float previous_amount = elem.amount;
1778 elem.amount /= 5;
1779 damage_blocked += previous_amount - elem.amount;
1780 }
1781 // electrical damage deals full damage if unarmed OR wielding a
1782 // conductive weapon
1783 } else if( elem.type == DT_ELECTRIC ) {
1784 // Unarmed weapons and conductive weapons won't block this
1785 if( item_blocking && !conductive_shield ) {
1786 float previous_amount = elem.amount;
1787 elem.amount /= 5;
1788 damage_blocked += previous_amount - elem.amount;
1789 }
1790 }
1791 }
1792
1793 std::string damage_blocked_description;
1794 // good/bad/ugly add_msg color code?
1795 // none, hardly any, a little, some, most, all
1796 float blocked_ratio = 0.0f;
1797 if( total_damage > std::numeric_limits<float>::epsilon() ) {
1798 blocked_ratio = ( total_damage - damage_blocked ) / total_damage;
1799 }
1800 if( blocked_ratio < std::numeric_limits<float>::epsilon() ) {
1801 //~ Damage amount in "You block <damage amount> with your <weapon>."
1802 damage_blocked_description = pgettext( "block amount", "all of the damage" );
1803 } else if( blocked_ratio < 0.2 ) {
1804 //~ Damage amount in "You block <damage amount> with your <weapon>."
1805 damage_blocked_description = pgettext( "block amount", "nearly all of the damage" );
1806 } else if( blocked_ratio < 0.4 ) {
1807 //~ Damage amount in "You block <damage amount> with your <weapon>."
1808 damage_blocked_description = pgettext( "block amount", "most of the damage" );
1809 } else if( blocked_ratio < 0.6 ) {
1810 //~ Damage amount in "You block <damage amount> with your <weapon>."
1811 damage_blocked_description = pgettext( "block amount", "a lot of the damage" );
1812 } else if( blocked_ratio < 0.8 ) {
1813 //~ Damage amount in "You block <damage amount> with your <weapon>."
1814 damage_blocked_description = pgettext( "block amount", "some of the damage" );
1815 } else if( blocked_ratio > std::numeric_limits<float>::epsilon() ) {
1816 //~ Damage amount in "You block <damage amount> with your <weapon>."
1817 damage_blocked_description = pgettext( "block amount", "a little of the damage" );
1818 } else {
1819 //~ Damage amount in "You block <damage amount> with your <weapon>."
1820 damage_blocked_description = pgettext( "block amount", "none of the damage" );
1821 }
1823 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1824 _( "You block %1$s with your %2$s!" ),
1825 //~ %1$s is damage amount string (e.g. "most of the damage"), %2$s is weapon name
1826 _( "<npcname> blocks %1$s with their %2$s!" ),
1827 damage_blocked_description, thing_blocked_with );
1828
1829 // fire martial arts block-triggered effects
1830 martial_arts_data->ma_onblock_effects( *this );
1831
1832 // Check if we have any block counters
1833 matec_id tec = pick_technique( *source, shield, false, false, true );
1834
1835 if( tec != tec_none && !is_dead_state() ) {
1836 if( get_stamina() < get_stamina_max() / 3 ) {
1837 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
1838 } else if( primary_weapon().made_of( material_id( "glass" ) ) ) {
1839 add_msg( m_bad, _( "The item you are wielding is too fragile to counterattack with!" ) );
1840 } else {
1841 melee_attack( *source, false, &tec );
1842 }
1843 }
1844
1845 return true;
1846}
std::string body_part_name(body_part bp, int number)
Returns the matching name of the body_part token.
Definition: bodypart.cpp:319
double logarithmic_range(int min, int max, int pos)
Normalized logistic function.
int blocks_left
Definition: character.h:568
matec_id pick_technique(Creature &t, const item &weap, bool crit, bool dodge_counter, bool block_counter)
Returns a random valid technique.
Definition: melee.cpp:1174
int mabuff_block_bonus() const
Returns the block bonus from martial arts buffs.
bool in_sleep_state() const override
Definition: character.cpp:9327
void melee_attack(Creature &t, bool allow_special, const matec_id *force_technique=nullptr, bool allow_unarmed=true)
Sets up a melee attack and handles melee attack function calls.
Definition: melee.cpp:445
bool handle_melee_wear(item &shield, float wear_multiplier=1.0f)
Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.
Definition: melee.cpp:217
item & best_shield()
Returns the best item for blocking with.
Definition: melee.cpp:1603
bool made_of(const material_id &m) const override
Definition: character.cpp:6252
virtual bool is_hallucination() const =0
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:689
int block_bonus
Definition: creature.h:840
bool conductive() const
Whether the items is conductive.
Definition: item.cpp:6488
bool is_null() const
Definition: item.cpp:737
@ DT_COLD
Definition: damage.h:29
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_narcosis("narcosis")
static const matec_id tec_none("tec_none")
static const skill_id skill_unarmed("unarmed")

References _, add_msg(), Creature::add_msg_player_or_npc(), best_shield(), Creature::block_bonus, blocking_ability(), blocks_left, body_part_name(), item::conductive(), item::covers(), damage_instance::damage_units, DT_ACID, DT_BASH, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_STAB, effect_narcosis, Creature::get_part_hp_cur(), get_skill_level(), get_stamina(), get_stamina_max(), handle_melee_wear(), Creature::has_effect(), item::has_flag(), in_sleep_state(), is_dead_state(), Creature::is_hallucination(), item::is_null(), logarithmic_range(), m_bad, mabuff_block_bonus(), made_of(), martial_arts_data, melee_attack(), pgettext(), pick_technique(), primary_weapon(), skill_melee, skill_unarmed, str_cur, tec_none, and item::tname().

◆ block_ranged_hit()

bool Character::block_ranged_hit ( Creature source,
bodypart_id bp_hit,
damage_instance dam 
)
overridevirtual

Checks for chance that a ranged attack will hit other armor along the way.

Implements Creature.

Definition at line 10749 of file character.cpp.

10750{
10751 // Having access to more than one shield is not normal in vanilla, for now keep it simple and only give one chance to catch a bullet.
10752 item &shield = best_shield();
10753
10754 // Bail out early just in case, if blocking with bare hands.
10755 if( shield.is_null() ) {
10756 return false;
10757 }
10758
10759 const auto level = shield_level( shield );
10760 if( level == ShieldLevel::None || !is_covered_by_shield( bp_hit, shield ) ) {
10761 return false;
10762 }
10763 // Modify chance based on coverage and blocking ability, with lowered chance if hitting the legs. Exclude armguards here.
10764 const float technic_modifier = coverage_modifier_by_technic( level, is_leg_hit( bp_hit ) );
10765 const float shield_coverage_modifier = shield.get_coverage() * technic_modifier;
10766
10767 add_msg( m_debug, _( "block_ranged_hit success rate: %i%%" ),
10768 static_cast<int>( shield_coverage_modifier ) );
10769
10770 // Now roll coverage to determine if we intercept the shot.
10771 if( rng( 1, 100 ) > shield_coverage_modifier ) {
10772 add_msg( m_debug, _( "block_ranged_hit attempt failed" ) );
10773 return false;
10774 }
10775
10776 const float wear_modifier = is_valid_hallucination( source ) ? 0.0f : 1.0f;
10777 handle_melee_wear( shield, wear_modifier );
10778
10779 int total_damage = 0;
10780 int blocked_damage = 0;
10781 for( auto &elem : dam.damage_units ) {
10782 total_damage += elem.amount * elem.damage_multiplier;
10783 // Go through all relevant damage types and reduce by armor value if one exists.
10784 const float block_amount = get_block_amount( shield, elem );
10785 elem.amount -= block_amount;
10786 blocked_damage += block_amount;
10787 }
10788 blocked_damage = std::min( total_damage, blocked_damage );
10789 add_msg( m_debug, _( "expected base damage: %i" ), total_damage );
10790
10791 const std::string thing_blocked_with = shield.tname();
10792 if( blocked_damage > 0 ) {
10794 _( "The shot hits your %s, absorbing %i damage." ),
10795 _( "The shot hits <npcname>'s %s, absorbing %i damage." ),
10796 thing_blocked_with, blocked_damage );
10797 } else {
10799 _( "The shot hits your %s, but it punches right through!" ),
10800 _( "The shot hits <npcname>'s %s, but it punches right through!" ),
10801 thing_blocked_with );
10802 }
10803 return true;
10804}
auto coverage_modifier_by_technic(ShieldLevel level, bool leg_hit) -> float
auto is_valid_hallucination(Creature *source) -> bool
auto get_block_amount(const item &shield, const damage_unit &unit) -> int
auto is_leg_hit(const bodypart_id &bp_hit) -> bool
auto shield_level(const item &shield) -> ShieldLevel
auto is_covered_by_shield(const bodypart_id &bp_hit, const item &shield) -> bool
Check if the given shield can protect the given bodypart.

References _, add_msg(), Creature::add_msg_player_or_npc(), best_shield(), anonymous_namespace{character.cpp}::coverage_modifier_by_technic(), damage_instance::damage_units, anonymous_namespace{character.cpp}::get_block_amount(), item::get_coverage(), handle_melee_wear(), anonymous_namespace{character.cpp}::is_covered_by_shield(), anonymous_namespace{character.cpp}::is_leg_hit(), item::is_null(), anonymous_namespace{character.cpp}::is_valid_hallucination(), m_debug, rng(), anonymous_namespace{character.cpp}::shield_level(), and item::tname().

◆ blood_loss()

int Character::blood_loss ( const bodypart_id bp) const

Define blood loss (in percents)

Definition at line 5730 of file character.cpp.

5731{
5732 int hp_cur_sum = get_part_hp_cur( bp );
5733 int hp_max_sum = get_part_hp_max( bp );
5734
5735 if( bp == bodypart_id( "leg_l" ) || bp == bodypart_id( "leg_r" ) ) {
5736 hp_cur_sum = get_part_hp_cur( bodypart_id( "leg_l" ) ) + get_part_hp_cur( bodypart_id( "leg_r" ) );
5737 hp_max_sum = get_part_hp_max( bodypart_id( "leg_l" ) ) + get_part_hp_max( bodypart_id( "leg_r" ) );
5738 } else if( bp == bodypart_id( "arm_l" ) || bp == bodypart_id( "arm_r" ) ) {
5739 hp_cur_sum = get_part_hp_cur( bodypart_id( "arm_l" ) ) + get_part_hp_cur( bodypart_id( "arm_r" ) );
5740 hp_max_sum = get_part_hp_max( bodypart_id( "arm_l" ) ) + get_part_hp_max( bodypart_id( "arm_r" ) );
5741 }
5742
5743 hp_cur_sum = std::min( hp_max_sum, std::max( 0, hp_cur_sum ) );
5744 hp_max_sum = std::max( hp_max_sum, 1 );
5745 return 100 - ( 100 * hp_cur_sum ) / hp_max_sum;
5746}
int get_part_hp_max(const bodypart_id &id) const
Definition: creature.cpp:1612

References Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

◆ bloodType()

field_type_id Character::bloodType ( ) const
overridevirtual

Implements Creature.

Definition at line 508 of file character.cpp.

509{
510 if( has_trait( trait_ACIDBLOOD ) ) {
511 return fd_acid;
512 }
514 return fd_blood_veggy;
515 }
517 return fd_blood_insect;
518 }
521 }
522 return fd_blood;
523}
static const trait_id trait_THRESH_CEPHALOPOD("THRESH_CEPHALOPOD")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const trait_id trait_THRESH_INSECT("THRESH_INSECT")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const trait_id trait_THRESH_SPIDER("THRESH_SPIDER")
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_acid
Definition: field_type.cpp:342

References fd_acid, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, has_trait(), trait_ACIDBLOOD, trait_THRESH_CEPHALOPOD, trait_THRESH_INSECT, trait_THRESH_PLANT, and trait_THRESH_SPIDER.

◆ blossoms()

void Character::blossoms ( )

Definition at line 8797 of file character.cpp.

8798{
8799 // Player blossoms are shorter-ranged, but you can fire much more frequently if you like.
8800 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8801 map &here = get_map();
8802 for( const tripoint &tmp : here.points_in_radius( pos(), 2 ) ) {
8803 here.add_field( tmp, fd_fungal_haze, rng( 1, 2 ) );
8804 }
8805}
field_type_id fd_fungal_haze
Definition: field_type.cpp:374

References _, sounds::combat, fd_fungal_haze, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), pos(), rng(), and sounds::sound().

Referenced by activate_mutation(), and suffer_while_awake().

◆ bmi()

float Character::bmi ( ) const

Definition at line 6758 of file character.cpp.

6759{
6760 return 25;
6761}

Referenced by bodyweight(), debug_menu::debug(), character_display::disp_info(), and suffer_mutation_power().

◆ bmr()

int Character::bmr ( ) const

Definition at line 6865 of file character.cpp.

6866{
6867 return metabolic_rate_base() * 2500;
6868}
float metabolic_rate_base() const
Stable base metabolic rate due to traits.

References metabolic_rate_base().

Referenced by debug_menu::debug(), fall_asleep(), get_hunger_description(), and update_stomach().

◆ body_window()

hp_part Character::body_window ( const std::string &  menu_header,
bool  show_all,
bool  precise,
int  normal_bonus,
int  head_bonus,
int  torso_bonus,
float  bleed,
float  bite,
float  infect,
float  bandage_power,
float  disinfectant_power 
) const

Displays menu with body part hp, optionally with hp estimation after healing.

Returns selected part. menu_header - name of item that triggers this menu show_all - show and enable choice of all limbs, not only healable precise - show numerical hp normal_bonus - heal normal limb head_bonus - heal head torso_bonus - heal torso bleed - chance to stop bleeding bite - chance to remove bite infect - chance to remove infection bandage_power - quality of bandage disinfectant_power - quality of disinfectant

Definition at line 5760 of file character.cpp.

5764{
5765 /* This struct establishes some kind of connection between the hp_part (which can be healed and
5766 * have HP) and the body_part. Note that there are more body_parts than hp_parts. For example:
5767 * Damage to bp_head, bp_eyes and bp_mouth is all applied on the HP of hp_head. */
5768 struct healable_bp {
5769 mutable bool allowed;
5770 bodypart_id bp;
5771 hp_part hp;
5772 std::string name; // Translated name as it appears in the menu.
5773 int bonus;
5774 };
5775 /* The array of the menu entries show to the player. The entries are displayed in this order,
5776 * it may be changed here. */
5777 std::array<healable_bp, num_hp_parts> parts = { {
5778 { false, bodypart_id( "head" ), hp_head, _( "Head" ), head_bonus },
5779 { false, bodypart_id( "torso" ), hp_torso, _( "Torso" ), torso_bonus },
5780 { false, bodypart_id( "arm_l" ), hp_arm_l, _( "Left Arm" ), normal_bonus },
5781 { false, bodypart_id( "arm_r" ), hp_arm_r, _( "Right Arm" ), normal_bonus },
5782 { false, bodypart_id( "leg_l" ), hp_leg_l, _( "Left Leg" ), normal_bonus },
5783 { false, bodypart_id( "leg_r" ), hp_leg_r, _( "Right Leg" ), normal_bonus },
5784 }
5785 };
5786
5787 int max_bp_name_len = 0;
5788 for( const auto &e : parts ) {
5789 max_bp_name_len = std::max( max_bp_name_len, utf8_width( e.name ) );
5790 }
5791
5792 uilist bmenu;
5793 bmenu.desc_enabled = true;
5794 bmenu.text = menu_header;
5795
5796 bmenu.hilight_disabled = true;
5797 bool is_valid_choice = false;
5798
5799 for( size_t i = 0; i < parts.size(); i++ ) {
5800 const auto &e = parts[i];
5801 const bodypart_id &bp = e.bp;
5802 const body_part bp_token = bp->token;
5803 const int maximal_hp = get_part_hp_max( bp );
5804 const int current_hp = get_part_hp_cur( bp );
5805 // This will c_light_gray if the part does not have any effects cured by the item/effect
5806 // (e.g. it cures only bites, but the part does not have a bite effect)
5807 const nc_color state_col = limb_color( bp, bleed > 0.0f, bite > 0.0f, infect > 0.0f );
5808 const bool has_curable_effect = state_col != c_light_gray;
5809 // The same as in the main UI sidebar. Independent of the capability of the healing item/effect!
5810 const nc_color all_state_col = limb_color( bp, true, true, true );
5811 // Broken means no HP can be restored, it requires surgical attention.
5812 const bool limb_is_broken = is_limb_broken( bp );
5813
5814 if( show_all ) {
5815 e.allowed = true;
5816 } else if( has_curable_effect ) {
5817 e.allowed = true;
5818 } else if( current_hp < maximal_hp && ( e.bonus != 0 || bandage_power > 0.0f ||
5819 disinfectant_power > 0.0f ) ) {
5820 e.allowed = true;
5821 } else {
5822 e.allowed = false;
5823 }
5824
5825 std::string msg;
5826 std::string desc;
5827 bool bleeding = has_effect( effect_bleed, bp_token );
5828 bool bitten = has_effect( effect_bite, bp_token );
5829 bool infected = has_effect( effect_infected, bp_token );
5830 bool bandaged = has_effect( effect_bandaged, bp_token );
5831 bool disinfected = has_effect( effect_disinfected, bp_token );
5832 const int b_power = get_effect_int( effect_bandaged, bp_token );
5833 const int d_power = get_effect_int( effect_disinfected, bp_token );
5834 int new_b_power = static_cast<int>( std::floor( bandage_power ) );
5835 if( bandaged ) {
5836 const effect &eff = get_effect( effect_bandaged, bp_token );
5837 if( new_b_power > eff.get_max_intensity() ) {
5838 new_b_power = eff.get_max_intensity();
5839 }
5840
5841 }
5842 int new_d_power = static_cast<int>( std::floor( disinfectant_power ) );
5843
5844 const auto &aligned_name = std::string( max_bp_name_len - utf8_width( e.name ), ' ' ) + e.name;
5845 std::string hp_str;
5846 if( limb_is_broken ) {
5847 const nc_color color = worn_with_flag( flag_SPLINT, bp ) ||
5848 ( mutation_value( "mending_modifier" ) >= 1.0f ) ?
5849 c_blue :
5851 desc += colorize( _( "It is broken and must heal fully before it becomes functional again." ),
5852 c_blue ) + "\n";
5853 const int mend_perc = 100 * current_hp / maximal_hp;
5854
5855 if( precise ) {
5856 hp_str = colorize( string_format( "=%2d%%=", mend_perc ), color );
5857 } else {
5858 const int num = mend_perc / 20;
5859 hp_str = colorize( std::string( num, '#' ) + std::string( 5 - num, '=' ), color );
5860 }
5861 } else if( precise ) {
5862 hp_str = string_format( "%d", current_hp );
5863 } else {
5864 std::pair<std::string, nc_color> h_bar = get_hp_bar( current_hp, maximal_hp, false );
5865 hp_str = colorize( h_bar.first, h_bar.second ) +
5866 colorize( std::string( 5 - utf8_width( h_bar.first ), '.' ), c_white );
5867 }
5868 msg += colorize( aligned_name, all_state_col ) + " " + hp_str;
5869
5870 // BLEEDING block
5871 if( bleeding ) {
5872 desc += colorize( string_format( "%s: %s", get_effect( effect_bleed, bp_token ).get_speed_name(),
5873 get_effect( effect_bleed, bp_token ).disp_short_desc() ), c_red ) + "\n";
5874 if( bleed > 0.0f ) {
5875 desc += colorize( string_format( _( "Chance to stop: %d %%" ),
5876 static_cast<int>( bleed * 100 ) ), c_light_green ) + "\n";
5877 } else {
5878 desc += colorize( _( "This will not stop the bleeding." ),
5879 c_yellow ) + "\n";
5880 }
5881 }
5882 // BANDAGE block
5883 if( bandaged ) {
5884 desc += string_format( _( "Bandaged [%s]" ), texitify_healing_power( b_power ) ) + "\n";
5885 if( new_b_power > b_power ) {
5886 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5887 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5888 } else if( new_b_power > 0 ) {
5889 desc += colorize( _( "You don't expect any improvement from using this." ), c_yellow ) + "\n";
5890 }
5891 } else if( new_b_power > 0 && e.allowed ) {
5892 desc += colorize( string_format( _( "Expected bandage quality: %s" ),
5893 texitify_healing_power( new_b_power ) ), c_light_green ) + "\n";
5894 }
5895 // BITTEN block
5896 if( bitten ) {
5897 desc += colorize( string_format( "%s: ", get_effect( effect_bite,
5898 bp_token ).get_speed_name() ), c_red );
5899 desc += colorize( _( "It has a deep bite wound that needs cleaning." ), c_red ) + "\n";
5900 if( bite > 0 ) {
5901 desc += colorize( string_format( _( "Chance to clean and disinfect: %d %%" ),
5902 static_cast<int>( bite * 100 ) ), c_light_green ) + "\n";
5903 } else {
5904 desc += colorize( _( "This will not help in cleaning this wound." ), c_yellow ) + "\n";
5905 }
5906 }
5907 // INFECTED block
5908 if( infected ) {
5910 bp_token ).get_speed_name() ), c_red );
5911 desc += colorize( _( "It has a deep wound that looks infected. Antibiotics might be required." ),
5912 c_red ) + "\n";
5913 if( infect > 0 ) {
5914 desc += colorize( string_format( _( "Chance to heal infection: %d %%" ),
5915 static_cast<int>( infect * 100 ) ), c_light_green ) + "\n";
5916 } else {
5917 desc += colorize( _( "This will not help in healing infection." ), c_yellow ) + "\n";
5918 }
5919 }
5920 // DISINFECTANT (general) block
5921 if( disinfected ) {
5922 desc += string_format( _( "Disinfected [%s]" ),
5923 texitify_healing_power( d_power ) ) + "\n";
5924 if( new_d_power > d_power ) {
5925 desc += colorize( string_format( _( "Expected quality improvement: %s" ),
5926 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5927 } else if( new_d_power > 0 ) {
5928 desc += colorize( _( "You don't expect any improvement from using this." ),
5929 c_yellow ) + "\n";
5930 }
5931 } else if( new_d_power > 0 && e.allowed ) {
5932 desc += colorize( string_format(
5933 _( "Expected disinfection quality: %s" ),
5934 texitify_healing_power( new_d_power ) ), c_light_green ) + "\n";
5935 }
5936 // END of blocks
5937
5938 if( ( !e.allowed && !limb_is_broken ) || ( show_all && current_hp == maximal_hp &&
5939 !limb_is_broken && !bitten && !infected && !bleeding ) ) {
5940 desc += colorize( _( "Healthy." ), c_green ) + "\n";
5941 }
5942 if( !e.allowed ) {
5943 desc += colorize( _( "You don't expect any effect from using this." ), c_yellow );
5944 } else {
5945 is_valid_choice = true;
5946 }
5947 bmenu.addentry_desc( i, e.allowed, MENU_AUTOASSIGN, msg, desc );
5948 }
5949
5950 if( !is_valid_choice ) { // no body part can be chosen for this item/effect
5951 bmenu.init();
5952 bmenu.desc_enabled = false;
5953 bmenu.text = _( "No limb would benefit from it." );
5954 bmenu.addentry( parts.size(), true, 'q', "%s", _( "Cancel" ) );
5955 }
5956
5957 bmenu.query();
5958 if( bmenu.ret >= 0 && static_cast<size_t>( bmenu.ret ) < parts.size() &&
5959 parts[bmenu.ret].allowed ) {
5960 return parts[bmenu.ret].hp;
5961 } else {
5962 return num_hp_parts;
5963 }
5964}
int utf8_width(const char *s, const bool ignore_tags)
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_infected("infected")
static const efftype_id effect_bite("bite")
static const std::string flag_SPLINT("SPLINT")
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3265
nc_color limb_color(const bodypart_id &bp, bool bleed, bool bite, bool infect) const
Definition: character.cpp:5966
bool is_limb_broken(const bodypart_id &limb) const
Returns true if the limb is broken.
Definition: character.cpp:1265
virtual void bleed() const
Adds an appropriate blood splatter.
Definition: creature.cpp:128
Definition: effect.h:164
int get_max_intensity() const
Returns the maximum intensity of an effect.
Definition: effect.cpp:853
int ret
Definition: ui.h:412
bool desc_enabled
Definition: ui.h:352
void addentry_desc(const std::string &str, const std::string &desc)
Definition: ui.cpp:952
bool hilight_disabled
Definition: ui.h:366
std::string text
Definition: ui.h:320
void addentry(const std::string &str)
Definition: ui.cpp:942
#define c_green
Definition: color.h:22
#define c_light_green
Definition: color.h:28
#define c_light_red
Definition: color.h:27
static nc_color color(const T_t &t)
std::string texitify_healing_power(const int power)
Definition: effect.cpp:1478
void query(bool loop=true, int timeout=-1)
Handle input and update display.
Definition: ui.cpp:838
void init()
Sane defaults on initialization.
Definition: ui.cpp:152
std::pair< std::string, nc_color > get_hp_bar(const int cur_hp, const int max_hp, const bool is_mon)
Definition: output.cpp:1604
hp_part
Definition: pldata.h:32
@ hp_torso
Definition: pldata.h:34
@ hp_leg_r
Definition: pldata.h:38
@ hp_arm_r
Definition: pldata.h:36
@ hp_head
Definition: pldata.h:33
@ hp_arm_l
Definition: pldata.h:35
@ num_hp_parts
Definition: pldata.h:39
@ hp_leg_l
Definition: pldata.h:37
@ hp
Drains HP to recharge.
const int MENU_AUTOASSIGN
Definition: ui.h:31

References _, uilist::addentry(), uilist::addentry_desc(), Creature::bleed(), c_blue, c_green, c_light_gray, c_light_green, c_light_red, c_red, c_white, c_yellow, color(), colorize(), uilist::desc_enabled, effect_bandaged, effect_bite, effect_bleed, effect_disinfected, effect_infected, flag_SPLINT(), Creature::get_effect(), Creature::get_effect_int(), get_hp_bar(), effect::get_max_intensity(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), Creature::has_effect(), uilist::hilight_disabled, hp, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, uilist::init(), is_limb_broken(), limb_color(), MENU_AUTOASSIGN, mutation_value(), name, num, num_hp_parts, uilist::query(), uilist::ret, string_format(), texitify_healing_power(), uilist::text, utf8_width(), and worn_with_flag().

Referenced by game::npc_menu(), and pick_part_to_heal().

◆ bodypart_exposure()

std::map< bodypart_id, float > Character::bodypart_exposure ( )

Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).

Clothing layers are multiplied, ex. two layers of 50% coverage will leave only 25% exposed. Used to determine suffering effects of albinism and solar sensitivity.

Definition at line 862 of file suffer.cpp.

863{
864 std::map<bodypart_id, float> bp_exposure;
865 // May need to iterate over all body parts several times, so make a copy
866 const std::vector<bodypart_id> all_body_parts = get_all_body_parts();
867
868 // Initially, all parts are assumed to be fully exposed
869 for( const bodypart_id &bp : all_body_parts ) {
870 bp_exposure[bp] = 1.0;
871 }
872 // For every item worn, for every body part, adjust coverage
873 for( const item &it : worn ) {
874 // What body parts does this item cover?
875 body_part_set covered = it.get_covered_body_parts();
876 for( const bodypart_id &bp : all_body_parts ) {
877 if( bp->token != num_bp && !covered.test( bp->token ) ) {
878 continue;
879 }
880 // How much exposure does this item leave on this part? (1.0 == naked)
881 float part_exposure = 1.0 - it.get_coverage() / 100.0f;
882 // Coverage multiplies, so two layers with 50% coverage will together give 75%
883 bp_exposure[bp] = bp_exposure[bp] * part_exposure;
884 }
885 }
886 return bp_exposure;
887}
@ num_bp
Definition: bodypart.h:54
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1674
bool test(const body_part &bp) const
Definition: bodypart.h:253

References all_body_parts, Creature::get_all_body_parts(), num_bp, body_part_set::test(), and worn.

Referenced by suffer_from_sunburn().

◆ bodytemp_color()

nc_color Character::bodytemp_color ( int  bp) const

Define color for displaying the body temperature.

Definition at line 10467 of file character.cpp.

10468{
10469 nc_color color = c_light_gray; // default
10470 if( bp == bp_eyes ) {
10471 color = c_light_gray; // Eyes don't count towards warmth
10472 } else if( temp_conv[bp] > BODYTEMP_SCORCHING ) {
10473 color = c_red;
10474 } else if( temp_conv[bp] > BODYTEMP_VERY_HOT ) {
10476 } else if( temp_conv[bp] > BODYTEMP_HOT ) {
10477 color = c_yellow;
10478 } else if( temp_conv[bp] > BODYTEMP_COLD ) {
10479 color = c_green;
10480 } else if( temp_conv[bp] > BODYTEMP_VERY_COLD ) {
10482 } else if( temp_conv[bp] > BODYTEMP_FREEZING ) {
10483 color = c_cyan;
10484 } else if( temp_conv[bp] <= BODYTEMP_FREEZING ) {
10485 color = c_blue;
10486 }
10487 return color;
10488}
#define c_cyan
Definition: color.h:24
static constexpr int BODYTEMP_SCORCHING
Definition: weather.h:42
static constexpr int BODYTEMP_VERY_HOT
Level 3 hotness.
Definition: weather.h:40
static constexpr int BODYTEMP_VERY_COLD
Frostbite timer will not improve while below this point.
Definition: weather.h:32
static constexpr int BODYTEMP_FREEZING
This value means frostbite occurs at the warmest temperature of 1C. If changed, the temp_conv calcula...
Definition: weather.h:30

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, c_blue, c_cyan, c_green, c_light_blue, c_light_gray, c_light_red, c_red, c_yellow, color(), and temp_conv.

Referenced by character_display::print_encumbrance().

◆ bodytemp_modifier_traits()

int Character::bodytemp_modifier_traits ( bool  overheated) const

Correction factor of the body temperature due to traits and mutations.

Definition at line 9551 of file character.cpp.

9552{
9553 int mod = 0;
9554 for( const trait_id &iter : get_mutations() ) {
9555 mod += overheated ? iter->bodytemp_min : iter->bodytemp_max;
9556 }
9557 return mod;
9558}
std::vector< trait_id > get_mutations(bool include_hidden=true) const
Get the idents of all traits/mutations.

References get_mutations().

Referenced by update_bodytemp().

◆ bodytemp_modifier_traits_floor()

int Character::bodytemp_modifier_traits_floor ( ) const

Correction factor of the body temperature due to traits and mutations for player lying on the floor.

Definition at line 9560 of file character.cpp.

9561{
9562 int mod = 0;
9563 for( const trait_id &iter : get_mutations() ) {
9564 mod += iter->bodytemp_sleep;
9565 }
9566 return mod;
9567}

References get_mutations().

Referenced by floor_warmth().

◆ bodyweight()

units::mass Character::bodyweight ( ) const

Definition at line 6763 of file character.cpp.

6764{
6765 return units::from_kilogram( bmi() * std::pow( height() / 100.0f, 2 ) );
6766}
int height() const
Definition: character.cpp:6844
float bmi() const
Definition: character.cpp:6758
constexpr quantity< value_type, mass_in_milligram_tag > from_kilogram(const value_type v)
Definition: units_mass.h:48

References bmi(), units::from_kilogram(), and height().

Referenced by get_weight(), and get_weight_string().

◆ bonus_damage()

float Character::bonus_damage ( bool  random) const

Returns the bonus bashing damage the player deals based on their stats.

Strength increases bashing damage

Definition at line 919 of file melee.cpp.

920{
921 /** @EFFECT_STR increases bashing damage */
922 if( random ) {
923 return rng_float( get_str() / 2.0f, get_str() );
924 }
925
926 return get_str() * 0.75f;
927}
virtual int get_str() const
Getters for stats exclusive to characters.
Definition: character.cpp:4089
type random()
Returns a random direction.
Definition: overmap.cpp:4231
double rng_float(double lo, double hi)
Definition: rng.cpp:28

References get_str(), om_direction::random(), and rng_float().

Referenced by draw_stats_info(), roll_bash_damage(), and set_stats().

◆ bonus_from_enchantments()

double Character::bonus_from_enchantments ( double  base,
enchant_vals::mod  value,
bool  round = false 
) const

Calculate bonus from enchantments for given base value.

Definition at line 7915 of file character.cpp.

7917{
7918 return enchantment_cache->calc_bonus( value, base, round );
7919}
pimpl< enchantment > enchantment_cache
Definition: character.h:2282

References enchantment_cache.

Referenced by armor_enchantment_adjust(), attack_cost(), calc_needs_rates(), get_stamina_max(), known_magic::mana_regen_rate(), known_magic::max_mana(), metabolic_rate_base(), run_cost(), and update_stamina().

◆ bp_to_hp()

hp_part Character::bp_to_hp ( body_part  bp)
static

Converts a body_part to an hp_part.

Definition at line 6461 of file character.cpp.

6462{
6463 switch( bp ) {
6464 case bp_head:
6465 case bp_eyes:
6466 case bp_mouth:
6467 return hp_head;
6468 case bp_torso:
6469 return hp_torso;
6470 case bp_arm_l:
6471 case bp_hand_l:
6472 return hp_arm_l;
6473 case bp_arm_r:
6474 case bp_hand_r:
6475 return hp_arm_r;
6476 case bp_leg_l:
6477 case bp_foot_l:
6478 return hp_leg_l;
6479 case bp_leg_r:
6480 case bp_foot_r:
6481 return hp_leg_r;
6482 default:
6483 return num_hp_parts;
6484 }
6485}

References bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_hp_parts.

Referenced by iexamine::autodoc(), explosion_handler::legacy_shrapnel(), explosion_handler::ExplosionProcess::project_shrapnel(), and heal_actor::use_healing_item().

◆ build_mut_dependency_map()

void Character::build_mut_dependency_map ( const trait_id mut,
std::unordered_map< trait_id, int > &  dependency_map,
int  distance 
)

Recursively traverses the mutation's prerequisites and replacements, building up a map.

Definition at line 7778 of file character.cpp.

7780{
7781 // Skip base traits and traits we've seen with a lower distance
7782 const auto lowest_distance = dependency_map.find( mut );
7783 if( !has_base_trait( mut ) && ( lowest_distance == dependency_map.end() ||
7784 distance < lowest_distance->second ) ) {
7785 dependency_map[mut] = distance;
7786 // Recurse over all prerequisite and replacement mutations
7787 const mutation_branch &mdata = mut.obj();
7788 for( const trait_id &i : mdata.prereqs ) {
7789 build_mut_dependency_map( i, dependency_map, distance + 1 );
7790 }
7791 for( const trait_id &i : mdata.prereqs2 ) {
7792 build_mut_dependency_map( i, dependency_map, distance + 1 );
7793 }
7794 for( const trait_id &i : mdata.replacements ) {
7795 build_mut_dependency_map( i, dependency_map, distance + 1 );
7796 }
7797 }
7798}
void build_mut_dependency_map(const trait_id &mut, std::unordered_map< trait_id, int > &dependency_map, int distance)
Recursively traverses the mutation's prerequisites and replacements, building up a map.
Definition: character.cpp:7778
bool has_base_trait(const trait_id &b) const
Returns true if the player has the entered starting trait.
Definition: mutation.cpp:119
const T & obj() const
Returns the actual object this id refers to.
Definition: achievement.cpp:63
std::vector< trait_id > replacements
Definition: mutation.h:265
std::vector< trait_id > prereqs
Definition: mutation.h:260
std::vector< trait_id > prereqs2
Definition: mutation.h:261

References build_mut_dependency_map(), has_base_trait(), string_id< T >::obj(), mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::replacements, and second.

Referenced by build_mut_dependency_map(), and set_highest_cat_level().

◆ burn_fuel()

bool Character::burn_fuel ( bionic bio,
bool  start = false 
)

Convert fuel to bionic power.

Definition at line 1195 of file bionics.cpp.

1196{
1197 if( ( bio.info().fuel_opts.empty() && !bio.info().is_remote_fueled ) ||
1199 return true;
1200 }
1201 const bool is_metabolism_powered = bio.is_this_fuel_powered( fuel_type_metabolism );
1202 const bool is_cable_powered = bio.info().is_remote_fueled;
1203 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1204 float effective_efficiency = get_effective_efficiency( bio, bio.info().fuel_efficiency );
1205
1206 if( is_cable_powered ) {
1207 const itype_id remote_fuel = find_remote_fuel();
1208 if( !remote_fuel.is_empty() ) {
1209 fuel_available.emplace_back( remote_fuel );
1210 if( remote_fuel == fuel_type_sun_light ) {
1211 const item *pack = item_worn_with_flag( "SOLARPACK_ON" );
1212 effective_efficiency = pack != nullptr ? pack->type->solar_efficiency : 0;
1213 }
1214 // TODO: check for available fuel in remote source
1215 } else if( !start ) {
1217 _( "Your %s runs out of fuel and turn off." ),
1218 _( "<npcname>'s %s runs out of fuel and turn off." ),
1219 bio.info().name );
1220 bio.powered = false;
1221 deactivate_bionic( bio, true );
1222 return false;
1223 }
1224 }
1225
1226 if( start && fuel_available.empty() ) {
1227 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to start." ),
1228 _( "<npcname>'s %s does not have enough fuel to start." ),
1229 bio.info().name );
1230 deactivate_bionic( bio );
1231 return false;
1232 }
1233 // don't produce power on start to avoid instant recharge exploit by turning bionic ON/OFF
1234 //in the menu
1235 if( !start ) {
1236 for( const itype_id &fuel : fuel_available ) {
1237 const item &tmp_fuel = item( fuel );
1238 const int fuel_energy = tmp_fuel.fuel_energy();
1239 const bool is_perpetual_fuel = tmp_fuel.has_flag( flag_PERPETUAL );
1240
1241 int current_fuel_stock;
1242 if( is_metabolism_powered ) {
1243 current_fuel_stock = std::max( 0.0f, get_stored_kcal() - 0.8f *
1244 max_stored_kcal() );
1245 } else if( is_perpetual_fuel ) {
1246 current_fuel_stock = 1;
1247 } else if( is_cable_powered ) {
1248 current_fuel_stock = std::stoi( get_value( "rem_" + fuel.str() ) );
1249 } else {
1250 current_fuel_stock = std::stoi( get_value( fuel.str() ) );
1251 }
1252
1253 if( !bio.has_flag( flag_SAFE_FUEL_OFF ) &&
1254 get_power_level() + units::from_kilojoule( fuel_energy ) * effective_efficiency
1255 > get_max_power_level() ) {
1256 if( !bio.is_auto_start_keep_full() ) {
1257 if( is_metabolism_powered ) {
1258 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste calories." ),
1259 _( "<npcname>'s %s turns off to not waste calories." ),
1260 bio.info().name );
1261 } else if( is_perpetual_fuel ) {
1262 add_msg_player_or_npc( m_info, _( "Your %s turns off after filling your power banks." ),
1263 _( "<npcname>'s %s turns off after filling their power banks." ),
1264 bio.info().name );
1265 } else {
1266 add_msg_player_or_npc( m_info, _( "Your %s turns off to not waste fuel." ),
1267 _( "<npcname>'s %s turns off to not waste fuel." ),
1268 bio.info().name );
1269 }
1270 }
1271 bio.powered = false;
1272 deactivate_bionic( bio, true );
1273 return false;
1274 } else {
1275 if( current_fuel_stock > 0 ) {
1276 map &here = get_map();
1277 if( is_metabolism_powered ) {
1278 const int kcal_consumed = fuel_energy;
1279 // 1kcal = 4187 J
1280 const units::energy power_gain = kcal_consumed * 4184_J * effective_efficiency;
1281 mod_stored_kcal( -kcal_consumed );
1282 mod_power_level( power_gain );
1283 } else if( is_perpetual_fuel ) {
1284 if( fuel == fuel_type_sun_light ) {
1285 if( g->is_in_sunlight( pos() ) ) {
1286 const weather_type_id &wtype = current_weather( pos() );
1287 const float tick_sunlight = incident_sunlight( wtype, calendar::turn );
1288 const double intensity = tick_sunlight / default_daylight_level();
1289 mod_power_level( units::from_kilojoule( fuel_energy ) * intensity * effective_efficiency );
1290 }
1291 } else if( fuel == fuel_type_wind ) {
1292 int vehwindspeed = 0;
1293 const optional_vpart_position vp = here.veh_at( pos() );
1294 if( vp ) {
1295 // vehicle velocity in mph
1296 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1297 }
1298 const weather_manager &wm = get_weather();
1299 const double windpower = get_local_windpower( wm.windspeed + vehwindspeed,
1301 g->is_sheltered( pos() ) );
1302 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_efficiency );
1303 } else {
1304 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1305 }
1306 } else if( is_cable_powered ) {
1307 int to_consume = 1;
1309 to_consume = 0;
1310 }
1311 const int unconsumed = consume_remote_fuel( to_consume );
1312 if( unconsumed == 0 && to_consume == 1 ) {
1313 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1314 current_fuel_stock -= 1;
1315 } else if( to_consume == 1 ) {
1316 current_fuel_stock = 0;
1317 }
1318 set_value( "rem_" + fuel.str(), std::to_string( current_fuel_stock ) );
1319 } else {
1320 current_fuel_stock -= 1;
1321 set_value( fuel.str(), std::to_string( current_fuel_stock ) );
1322 update_fuel_storage( fuel );
1323 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_efficiency );
1324 }
1325
1326 heat_emission( bio, fuel_energy );
1327 if( bio.info().power_gen_emission ) {
1328 here.emit_field( pos(), bio.info().power_gen_emission );
1329 }
1330 } else {
1331
1332 if( is_metabolism_powered ) {
1334 _( "Stored calories are below the safe threshold, your %s shuts down to preserve your health." ),
1335 _( "Stored calories are below the safe threshold, <npcname>'s %s shuts down to preserve their health." ),
1336 bio.info().name );
1337 } else {
1338 remove_value( fuel.str() );
1340 _( "Your %s runs out of fuel and turn off." ),
1341 _( "<npcname>'s %s runs out of fuel and turn off." ),
1342 bio.info().name );
1343 }
1344
1345 bio.powered = false;
1346 deactivate_bionic( bio, true );
1347 return false;
1348 }
1349 }
1350 }
1351 }
1352 return true;
1353}
static const std::string flag_SAFE_FUEL_OFF("SAFE_FUEL_OFF")
static const std::string flag_PERPETUAL("PERPETUAL")
static const itype_id fuel_type_wind("wind")
static const itype_id fuel_type_metabolism("metabolism")
static const itype_id fuel_type_muscle("muscle")
static const itype_id fuel_type_sun_light("sunlight")
double default_daylight_level()
How much light is provided in full daylight.
Definition: calendar.cpp:62
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
std::vector< itype_id > get_fuel_available(const bionic_id &bio) const
Return list of available fuel for this bionic.
Definition: character.cpp:2014
const item * item_worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns the first worn item with a given flag.
Definition: character.cpp:3273
virtual void mod_stored_kcal(int nkcal)
Modifiers for need values exclusive to characters.
Definition: character.cpp:4324
void heat_emission(bionic &bio, int fuel_energy)
Handle heat from exothermic power generation.
Definition: bionics.cpp:1496
float get_effective_efficiency(bionic &bio, float fuel_efficiency)
Applies modifier to fuel_efficiency and returns the resulting efficiency.
Definition: bionics.cpp:1516
int get_stored_kcal() const
Getter for need values exclusive to characters.
Definition: character.cpp:4319
int consume_remote_fuel(int amount)
Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally succes...
Definition: bionics.cpp:1453
void update_fuel_storage(const itype_id &fuel)
Updates which bionic contain fuel and which is empty.
Definition: character.cpp:2069
itype_id find_remote_fuel(bool look_only=false)
Find fuel used by remote powered bionic.
Definition: bionics.cpp:1399
void set_value(const std::string &key, const std::string &value)
Definition: creature.cpp:1372
float fuel_energy() const
Returns energy of one charge of this item as fuel for an engine.
Definition: item.cpp:6826
const itype * type
Definition: item.h:2170
int winddirection
Definition: weather.h:194
const weather_type_id & current_weather(const tripoint &location, const time_point &t)
Definition: weather.cpp:143
int incident_sunlight(const weather_type_id &wtype, const time_point &t)
Amount of sunlight incident at the ground, taking weather and time of day into account.
Definition: weather.cpp:107
emit_id power_gen_emission
Type of field emitted by this bionic when it produces energy.
Definition: bionics.h:81
std::vector< itype_id > fuel_opts
Fuel types that can be used by this bionic.
Definition: bionics.h:67
float fuel_efficiency
Fraction of fuel energy converted to bionic power.
Definition: bionics.h:71
bool has_flag(const std::string &flag) const
Definition: bionics.cpp:2724
bool is_this_fuel_powered(const itype_id &this_fuel) const
Definition: bionics.cpp:2739
float solar_efficiency
Efficiency of solar energy conversion for solarpacks.
Definition: itype.h:1004

References _, Creature::add_msg_player_or_npc(), consume_remote_fuel(), current_weather(), deactivate_bionic(), default_daylight_level(), find_remote_fuel(), flag_PERPETUAL(), flag_SAFE_FUEL_OFF(), units::from_kilojoule(), bionic_data::fuel_efficiency, item::fuel_energy(), bionic_data::fuel_opts, fuel_type_metabolism, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_max_power_level(), get_power_level(), get_stored_kcal(), Creature::get_value(), get_weather(), global_omt_location(), bionic::has_flag(), item::has_flag(), heat_emission(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), bionic::id, incident_sunlight(), bionic::info(), bionic::is_auto_start_keep_full(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, bionic::is_this_fuel_powered(), item_worn_with_flag(), m_bad, m_info, max_stored_kcal(), mod_power_level(), mod_stored_kcal(), bionic_data::name, overmap_buffer, pos(), bionic_data::power_gen_emission, bionic::powered, Creature::remove_value(), Creature::set_value(), itype::solar_efficiency, overmapbuffer::ter(), to_string(), calendar::turn, item::type, update_fuel_storage(), weather_manager::winddirection, and weather_manager::windspeed.

Referenced by activate_bionic(), and process_bionic().

◆ burn_move_stamina()

void Character::burn_move_stamina ( int  moves)

Definition at line 7124 of file character.cpp.

7125{
7126 int overburden_percentage = 0;
7127 units::mass current_weight = weight_carried();
7128 // Make it at least 1 gram to avoid divide-by-zero warning
7129 units::mass max_weight = std::max( weight_capacity(), 1_gram );
7130 if( current_weight > max_weight ) {
7131 overburden_percentage = ( current_weight - max_weight ) * 100 / max_weight;
7132 }
7133
7134 int burn_ratio = get_option<int>( "PLAYER_BASE_STAMINA_BURN_RATE" );
7135 for( const bionic_id &bid : get_bionic_fueled_with( item( "muscle" ) ) ) {
7136 if( has_active_bionic( bid ) ) {
7137 burn_ratio = burn_ratio * 2 - 3;
7138 }
7139 }
7140 burn_ratio += overburden_percentage;
7141 if( move_mode == CMM_RUN ) {
7142 burn_ratio = burn_ratio * 7;
7143 }
7144 mod_stamina( -( ( moves * burn_ratio ) / 100.0 ) * stamina_move_cost_modifier() );
7145 add_msg( m_debug, "Stamina burn: %d", -( ( moves * burn_ratio ) / 100 ) );
7146 // Chance to suffer pain if overburden and stamina runs out or has trait BADBACK
7147 // Starts at 1 in 25, goes down by 5 for every 50% more carried
7148 if( ( current_weight > max_weight ) && ( has_trait( trait_BADBACK ) || get_stamina() == 0 ) &&
7149 one_in( 35 - 5 * current_weight / ( max_weight / 2 ) ) ) {
7150 add_msg_if_player( m_bad, _( "Your body strains under the weight!" ) );
7151 // 1 more pain for every 800 grams more (5 per extra STR needed)
7152 if( ( ( current_weight - max_weight ) / 800_gram > get_pain() && get_pain() < 100 ) ) {
7153 mod_pain( 1 );
7154 }
7155 }
7156}
static const trait_id trait_BADBACK("BADBACK")
std::vector< bionic_id > get_bionic_fueled_with(const item &it) const
Return bionic_id of bionics able to use it as fuel.
Definition: character.cpp:1866
units::mass weight_carried() const
Definition: character.cpp:2538
void mod_stamina(int mod)
Definition: character.cpp:7114
float stamina_move_cost_modifier() const
Definition: character.cpp:7158
virtual int get_pain() const
Definition: creature.cpp:1407

References _, add_msg(), Creature::add_msg_if_player(), CMM_RUN, get_bionic_fueled_with(), Creature::get_pain(), get_stamina(), has_active_bionic(), has_trait(), m_bad, m_debug, mod_pain(), mod_stamina(), move_mode, Creature::moves, one_in(), stamina_move_cost_modifier(), trait_BADBACK, weight_capacity(), and weight_carried().

Referenced by avatar_action::swim(), and game::walk_move().

◆ calc_all_parts_hp()

void Character::calc_all_parts_hp ( float  hp_mod = 0.0,
float  hp_adjust = 0.0,
int  str_max = 0 
)

Sets hp for all body parts.

Definition at line 1600 of file character.cpp.

1601{
1602 for( const std::pair<const bodypart_str_id, bodypart> &part : get_body() ) {
1603 bodypart &bp = get_part( part.first );
1604 int new_max = ( part.first->base_hp + str_max * 3 + hp_adjustment ) * hp_mod;
1605
1606 if( has_trait( trait_id( "GLASSJAW" ) ) && part.first == bodypart_str_id( "head" ) ) {
1607 new_max *= 0.8;
1608 }
1609
1610 float max_hp_ratio = static_cast<float>( new_max ) /
1611 static_cast<float>( bp.get_hp_max() );
1612
1613 int new_cur = std::ceil( static_cast<float>( bp.get_hp_cur() ) * max_hp_ratio );
1614
1615 bp.set_hp_max( std::max( new_max, 1 ) );
1616 bp.set_hp_cur( std::max( std::min( new_cur, new_max ), 0 ) );
1617 }
1618}
string_id< body_part_type > bodypart_str_id
Definition: bodypart.h:24
bodypart & get_part(const bodypart_id &id)
Definition: creature.cpp:1585
const std::map< bodypart_str_id, bodypart > & get_body() const
Definition: creature.cpp:1569
int get_hp_max() const
Definition: bodypart.cpp:402
int get_hp_cur() const
Definition: bodypart.cpp:397
void set_hp_max(int set)
Definition: bodypart.cpp:427
void set_hp_cur(int set)
Definition: bodypart.cpp:422

References Creature::get_body(), bodypart::get_hp_cur(), bodypart::get_hp_max(), Creature::get_part(), has_trait(), bodypart::set_hp_cur(), bodypart::set_hp_max(), str_max, and trait_id.

Referenced by recalc_hp().

◆ calc_encumbrance() [1/2]

char_encumbrance_data Character::calc_encumbrance ( ) const
protected

Recalculate encumbrance for all body parts.

Definition at line 3672 of file character.cpp.

3673{
3674 return calc_encumbrance( item() );
3675}
char_encumbrance_data calc_encumbrance() const
Recalculate encumbrance for all body parts.
Definition: character.cpp:3672

References calc_encumbrance().

Referenced by calc_encumbrance(), get_encumbrance(), on_item_takeoff(), on_item_wear(), and reset_encumbrance().

◆ calc_encumbrance() [2/2]

char_encumbrance_data Character::calc_encumbrance ( const item new_item) const
protected

Recalculate encumbrance for all body parts as if new_item was also worn.

Definition at line 3677 of file character.cpp.

3678{
3679
3681
3682 item_encumb( enc, new_item );
3683 mut_cbm_encumb( enc );
3684
3685 return enc;
3686}
void item_encumb(char_encumbrance_data &vals, const item &new_item) const
Applies encumbrance from items only If new_item is not null, then calculate under the asumption that ...
Definition: character.cpp:3983
void mut_cbm_encumb(char_encumbrance_data &vals) const
Applies encumbrance from mutations and bionics only.
Definition: character.cpp:4046

References item_encumb(), and mut_cbm_encumb().

◆ calc_needs_rates()

needs_rates Character::calc_needs_rates ( ) const

Definition at line 4929 of file character.cpp.

4930{
4931 const effect &sleep = get_effect( effect_sleep );
4932 const bool has_recycler = has_bionic( bio_recycler );
4933 const bool asleep = !sleep.is_null();
4934
4935 needs_rates rates;
4936 rates.hunger = metabolic_rate();
4937
4938 add_msg_if_player( m_debug, "Metabolic rate: %.2f", rates.hunger );
4939
4940 static const std::string player_thirst_rate( "PLAYER_THIRST_RATE" );
4941 rates.thirst = get_option< float >( player_thirst_rate );
4942 static const std::string thirst_modifier( "thirst_modifier" );
4943 rates.thirst *= 1.0f + mutation_value( thirst_modifier ) +
4945 static const std::string slows_thirst( "SLOWS_THIRST" );
4946 if( worn_with_flag( slows_thirst ) ) {
4947 rates.thirst *= 0.7f;
4948 }
4949
4950 static const std::string player_fatigue_rate( "PLAYER_FATIGUE_RATE" );
4951 rates.fatigue = get_option< float >( player_fatigue_rate );
4952 static const std::string fatigue_modifier( "fatigue_modifier" );
4953 rates.fatigue *= 1.0f + mutation_value( fatigue_modifier ) +
4955
4956 // Note: intentionally not in metabolic rate
4957 if( has_recycler ) {
4958 // Recycler won't help much with mutant metabolism - it is intended for human one
4959 rates.hunger = std::min( rates.hunger, std::max( 0.5f, rates.hunger - 0.5f ) );
4960 rates.thirst = std::min( rates.thirst, std::max( 0.5f, rates.thirst - 0.5f ) );
4961 }
4962
4963 if( asleep ) {
4964 static const std::string fatigue_regen_modifier( "fatigue_regen_modifier" );
4965 // Multiplied by 2 to account for legacy (bugged to always apply)
4966 // bonus for sleeping over 2 hours
4967 rates.recovery = 2.0f * ( 1.0f + mutation_value( fatigue_regen_modifier ) );
4968 if( is_hibernating() ) {
4969 // Hunger and thirst advance *much* more slowly whilst we hibernate.
4970 rates.hunger *= ( 1.0f / 7.0f );
4971 rates.thirst *= ( 1.0f / 7.0f );
4972 }
4973 rates.recovery -= static_cast<float>( get_perceived_pain() ) / 60;
4974
4975 } else {
4976 rates.recovery = 0;
4977 }
4978
4980 // Much of the body's needs are taken care of by the trees.
4981 // Hair Roots don't provide any bodily needs.
4983 rates.hunger *= 0.5f;
4984 rates.thirst *= 0.5f;
4985 rates.fatigue *= 0.5f;
4986 }
4987 }
4988
4990 // Transpiration, the act of moving nutrients with evaporating water, can take a very heavy toll on your thirst when it's really hot.
4991 rates.thirst *= ( ( get_weather().get_temperature( pos() ) - 32.5f ) / 40.0f );
4992 }
4993
4994 if( is_npc() ) {
4995 rates.hunger *= 0.25f;
4996 rates.thirst *= 0.25f;
4997 }
4998
4999 rates.thirst = std::max( rates.thirst, 0.0f );
5000 rates.hunger = std::max( rates.hunger, 0.0f );
5001 rates.fatigue = std::max( rates.fatigue, 0.0f );
5002 rates.recovery = std::max( rates.recovery, 0.0f );
5003
5004 return rates;
5005}
static const activity_id ACT_TREE_COMMUNION("ACT_TREE_COMMUNION")
static const trait_id trait_ROOTS2("ROOTS2")
static const bionic_id bio_recycler("bio_recycler")
static const efftype_id effect_sleep("sleep")
static const trait_id trait_TRANSPIRATION("TRANSPIRATION")
static const trait_id trait_ROOTS3("ROOTS3")
float metabolic_rate() const
Current metabolic rate due to traits, hunger, speed, etc.
bool is_hibernating() const
Returns if the player has hibernation mutation and is asleep and well fed.
Definition: character.cpp:5186
bool has_activity(const activity_id &type) const
Check if player currently has a given activity.
Definition: character.cpp:9229
int get_perceived_pain() const override
Returns perceived pain (reduced with painkillers)
Definition: character.cpp:803
int get_temperature(const tripoint &location) const
Definition: weather.cpp:1113
@ sleep
Will recharge only when character is asleep.
float hunger
Definition: character.h:203
float recovery
Definition: character.h:205
float fatigue
Definition: character.h:204
float thirst
Definition: character.h:202

References ACT_TREE_COMMUNION, Creature::add_msg_if_player(), bio_recycler, bonus_from_enchantments(), effect_sleep, needs_rates::fatigue, enchant_vals::FATIGUE, Creature::get_effect(), get_perceived_pain(), weather_manager::get_temperature(), get_weather(), has_activity(), has_bionic(), has_trait(), needs_rates::hunger, is_hibernating(), Creature::is_npc(), m_debug, metabolic_rate(), mutation_value(), pos(), needs_rates::recovery, sleep, needs_rates::thirst, enchant_vals::THIRST, trait_ROOTS2, trait_ROOTS3, trait_TRANSPIRATION, and worn_with_flag().

Referenced by update_needs(), and update_stomach().

◆ can_consume()

bool Character::can_consume ( const item it) const

Check character's capability of consumption overall.

Definition at line 1467 of file consumption.cpp.

1468{
1469 if( can_consume_as_is( it ) ) {
1470 return true;
1471 }
1472 // Checking NO_RELOAD to prevent consumption of `battery` when contained in `battery_car` (#20012)
1473 return !it.is_container_empty() && !it.has_flag( flag_NO_RELOAD ) &&
1475}
bool can_consume_as_is(const item &it) const
Check whether character can consume this very item.
item & front()
this is an artifact of the previous code using front() everywhere for contents.
bool is_container_empty() const
Whether this item has no contents at all.
Definition: item.cpp:6847
static const std::string flag_NO_RELOAD("NO_RELOAD")

References can_consume_as_is(), item::contents, flag_NO_RELOAD(), item_contents::front(), item::has_flag(), and item::is_container_empty().

Referenced by find_auto_consume(), and examine_item_menu::rate_action_eat().

◆ can_consume_as_is()

bool Character::can_consume_as_is ( const item it) const

Check whether character can consume this very item.

Definition at line 1457 of file consumption.cpp.

1458{
1459 return it.is_comestible() || can_consume_for_bionic( it );
1460}
bool can_consume_for_bionic(const item &it) const
bool is_comestible() const
Definition: item.cpp:6597

References can_consume_for_bionic(), and item::is_comestible().

Referenced by can_consume(), consume(), avatar_action::eat(), and get_consumable_from().

◆ can_consume_for_bionic()

bool Character::can_consume_for_bionic ( const item it) const

Definition at line 1462 of file consumption.cpp.

1463{
1465}
rechargeable_cbm get_cbm_rechargeable_with(const item &it) const

References get_cbm_rechargeable_with(), and none.

Referenced by can_consume_as_is().

◆ can_eat()

ret_val< edible_rating > Character::can_eat ( const item food) const

Can the food be [theoretically] eaten no matter the consequen ces?

Definition at line 642 of file consumption.cpp.

643{
644
645 const auto &comest = food.get_comestible();
646 if( !comest ) {
647 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible." ) );
648 }
649
650 if( food.has_flag( flag_INEDIBLE ) ) {
651 if( ( food.has_flag( flag_CATTLE ) && !has_trait( trait_THRESH_CATTLE ) ) ||
654 ( food.has_flag( flag_BIRD ) && !has_trait( trait_THRESH_BIRD ) ) ) {
655 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible to you." ) );
656 }
657 }
658
659 if( food.is_craft() ) {
660 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
661 }
662
663 if( food.has_own_flag( "DIRTY" ) ) {
665 _( "This is full of dirt after being on the ground." ) );
666 }
667
668 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
669 const bool edible = eat_verb || comest->comesttype == comesttype_FOOD;
670 const bool drinkable = !eat_verb && comest->comesttype == comesttype_DRINK;
671
672 // TODO: This condition occurs way too often. Unify it.
673 // update Sep. 26 2018: this apparently still occurs way too often. yay!
675 return ret_val<edible_rating>::make_failure( _( "You can't do that while underwater." ) );
676 }
677
678 if( edible || drinkable ) {
679 for( const auto &elem : food.type->materials ) {
680 if( !elem->edible() ) {
681 return ret_val<edible_rating>::make_failure( _( "That doesn't look edible in its current form." ) );
682 }
683 }
684 }
685
686 if( !comest->tool.is_null() ) {
687 const bool has = item::count_by_charges( comest->tool )
688 ? has_charges( comest->tool, 1 )
689 : has_amount( comest->tool, 1 );
690 if( !has ) {
692 string_format( _( "You need a %s to consume that!" ),
693 item::nname( comest->tool ) ) );
694 }
695 }
696
697 // For all those folks who loved eating marloss berries. D:< mwuhahaha
699 !food.has_flag( flag_NO_INGEST ) ) {
701 _( "We can't eat that. It's not right for us." ) );
702 }
703 // Here's why PROBOSCIS is such a negative trait.
704 if( has_trait( trait_PROBOSCIS ) && !( drinkable || food.is_medication() ) ) {
706 _( "Ugh, you can't drink that!" ) );
707 }
708 if( has_trait( trait_CARNIVORE ) && ( compute_effective_nutrients( food ).kcal ) > 0 &&
711 _( "Eww. Inedible plant stuff!" ) );
712 }
713
716 // Like non-cannibal, but more strict!
718 _( "The thought of eating that makes you feel sick." ) );
719 }
720
721 for( const trait_id &mut : get_mutations() ) {
722 if( !food.made_of_any( mut.obj().can_only_eat ) && !mut.obj().can_only_eat.empty() &&
723 !food.has_flag( flag_NO_INGEST ) ) {
725 _( "You can't eat this." ) );
726 }
727 }
728
730}
nutrients compute_effective_nutrients(const item &) const
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: character.cpp:9608
bool count_by_charges() const
Definition: item.cpp:6015
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10131
static std::string nname(const itype_id &id, unsigned int quantity=1)
Returns the translated item name for the item with given id.
Definition: item.cpp:9929
bool is_craft() const
Definition: item.cpp:6933
bool made_of_any(const std::set< material_id > &mat_idents) const
Check we are made of at least one of a set (e.g.
Definition: item.cpp:6445
bool is_medication() const
Definition: item.cpp:6608
bool has_any_flag(const Container &flags) const
Definition: item.h:1417
bool has_own_flag(const std::string &flag) const
Checks whether item itself has given flag (doesn't check item type or gunmods).
Definition: item.cpp:5325
static ret_val make_success(T val=default_success::value)
Definition: ret_val.h:42
static ret_val make_failure(T val=default_failure::value)
Definition: ret_val.h:46
bool has_amount(const itype_id &what, int qty, bool pseudo=true, const std::function< bool(const item &)> &filter=return_true< item >) const
Check instance provides at least qty of an item (.
Definition: visitable.cpp:1112
static const trait_id trait_RUMINANT("RUMINANT")
const std::vector< std::string > carnivore_blacklist
static const std::string flag_INEDIBLE("INEDIBLE")
static const trait_id trait_HERBIVORE("HERBIVORE")
static const trait_id trait_CARNIVORE("CARNIVORE")
static const std::string comesttype_DRINK("DRINK")
static const trait_id trait_THRESH_BIRD("THRESH_BIRD")
const std::vector< std::string > herbivore_blacklist(temparray.begin(), temparray.end())
static const std::string flag_BIRD("BIRD")
static const trait_id trait_PROBOSCIS("PROBOSCIS")
static const std::string flag_USE_EAT_VERB("USE_EAT_VERB")
static const std::string flag_MYCUS_OK("MYCUS_OK")
static const std::string flag_CATTLE("CATTLE")
static const trait_id trait_THRESH_LUPINE("THRESH_LUPINE")
static const trait_id trait_THRESH_CATTLE("THRESH_CATTLE")
static const trait_id trait_THRESH_FELINE("THRESH_FELINE")
static const std::string comesttype_FOOD("FOOD")
static const std::string flag_CARNIVORE_OK("CARNIVORE_OK")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const std::string flag_FELINE("FELINE")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
static const std::string flag_NO_INGEST("NO_INGEST")
static const std::string flag_LUPINE("LUPINE")
std::vector< material_id > materials
Definition: itype.h:893

References _, carnivore_blacklist, comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), item::count_by_charges(), edible, flag_BIRD(), flag_CARNIVORE_OK(), flag_CATTLE(), flag_FELINE(), flag_INEDIBLE(), flag_LUPINE(), flag_MYCUS_OK(), flag_NO_INGEST(), flag_USE_EAT_VERB(), item::get_comestible(), get_mutations(), visitable< Character >::has_amount(), item::has_any_flag(), has_charges(), item::has_flag(), item::has_own_flag(), has_trait(), herbivore_blacklist(), inedible_mutation, item::is_craft(), item::is_medication(), item::is_null(), Creature::is_underwater(), item::made_of_any(), ret_val< T >::make_failure(), ret_val< T >::make_success(), itype::materials, item::nname(), no_tool, string_format(), trait_CARNIVORE, trait_HERBIVORE, trait_M_DEPENDENT, trait_PROBOSCIS, trait_RUMINANT, trait_THRESH_BIRD, trait_THRESH_CATTLE, trait_THRESH_FELINE, trait_THRESH_LUPINE, trait_WATERSLEEP, and item::type.

Referenced by can_feed_furnace_with(), eat(), and will_eat().

◆ can_estimate_rot()

bool Character::can_estimate_rot ( ) const

True if the character has enough skill (in cooking or survival) to estimate time to rot.

Definition at line 1452 of file consumption.cpp.

1453{
1455}
static const skill_id skill_survival("survival")
static const skill_id skill_cooking("cooking")

References get_skill_level(), skill_cooking, and skill_survival.

Referenced by get_freshness_description().

◆ can_feed_furnace_with()

bool Character::can_feed_furnace_with ( const item it) const

Determine character's capability of recharging their CBMs.

Definition at line 1276 of file consumption.cpp.

1277{
1278 if( !it.flammable() || it.has_flag( flag_RADIOACTIVE ) || can_eat( it ).success() ) {
1279 return false;
1280 }
1281
1282 if( !has_active_bionic( bio_furnace ) ) {
1283 return false;
1284 }
1285
1286 // Not even one charge fits
1287 if( it.charges_per_volume( furnace_max_volume ) < 1 ) {
1288 return false;
1289 }
1290
1291 return !it.has_flag( flag_CORPSE );
1292}
ret_val< edible_rating > can_eat(const item &food) const
Can the food be [theoretically] eaten no matter the consequen ces?
bool flammable(int threshold=0) const
Whether the items is flammable.
Definition: item.cpp:8322
int charges_per_volume(const units::volume &vol) const
Number of (charges of) this item that fit into the given volume.
Definition: item.cpp:869
const units::volume furnace_max_volume(3_liter)
static const bionic_id bio_furnace("bio_furnace")
static const std::string flag_CORPSE("CORPSE")
static const std::string flag_RADIOACTIVE("RADIOACTIVE")

References bio_furnace, can_eat(), item::charges_per_volume(), flag_CORPSE(), flag_RADIOACTIVE(), item::flammable(), furnace_max_volume, has_active_bionic(), item::has_flag(), and behavior::success.

Referenced by feed_furnace_with(), and get_cbm_rechargeable_with().

◆ can_fuel_bionic_with()

bool Character::can_fuel_bionic_with ( const item it) const

Returns true if the character can fuel a bionic with the item.

Definition at line 1850 of file character.cpp.

1851{
1852 if( !it.is_fuel() ) {
1853 return false;
1854 }
1855
1856 for( const bionic_id &bid : get_bionics() ) {
1857 for( const itype_id &fuel : bid->fuel_opts ) {
1858 if( fuel == it.typeId() ) {
1859 return true;
1860 }
1861 }
1862 }
1863 return false;
1864}
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8359
bool is_fuel() const
Definition: item.cpp:6770

References get_bionics(), item::is_fuel(), and item::typeId().

Referenced by fuel_bionic_with(), and get_cbm_rechargeable_with().

◆ can_hear()

bool Character::can_hear ( const tripoint source,
int  volume 
) const

Definition at line 10286 of file character.cpp.

10287{
10288 if( is_deaf() ) {
10289 return false;
10290 }
10291
10292 // source is in-ear and at our square, we can hear it
10293 if( source == pos() && volume == 0 ) {
10294 return true;
10295 }
10296 const int dist = rl_dist( source, pos() );
10297 const float volume_multiplier = hearing_ability();
10298 return ( volume - get_weather().weather_id->sound_attn ) * volume_multiplier >= dist;
10299}
float hearing_ability() const
bool is_deaf() const
Definition: character.cpp:4511
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16

References get_weather(), hearing_ability(), is_deaf(), pos(), and rl_dist().

Referenced by game::chat(), iuse::geiger(), iuse::play_music(), iuse::talking_doll(), and musical_instrument_actor::use().

◆ can_install_bionics()

bool Character::can_install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is the installation possible.

Definition at line 2206 of file bionics.cpp.

2208{
2209 if( !type.bionic ) {
2210 debugmsg( "Tried to install NULL bionic" );
2211 return false;
2212 }
2213 if( is_mounted() ) {
2214 return false;
2215 }
2216
2217 const bionic_id &bioid = type.bionic->id;
2218 const int difficult = type.bionic->difficulty;
2219 float adjusted_skill;
2220
2221 if( autodoc ) {
2222 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2225 skill_level );
2226 } else {
2227 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2230 skill_level );
2231 }
2232 int chance_of_success = bionic_manip_cos( adjusted_skill, difficult );
2233
2234 std::vector<std::string> conflicting_muts;
2235 for( const trait_id &mid : bioid->canceled_mutations ) {
2236 if( has_trait( mid ) ) {
2237 conflicting_muts.push_back( mid->name() );
2238 }
2239 }
2240
2241 if( !conflicting_muts.empty() &&
2242 !query_yn(
2243 _( "Installing this bionic will remove the conflicting traits: %s. Continue anyway?" ),
2244 enumerate_as_string( conflicting_muts ) ) ) {
2245 return false;
2246 }
2247
2248 const std::map<bodypart_id, int> &issues = bionic_installation_issues( bioid );
2249 // show all requirements which are not satisfied
2250 if( !issues.empty() ) {
2251 std::string detailed_info;
2252 for( auto &elem : issues ) {
2253 //~ <Body part name>: <number of slots> more slot(s) needed.
2254 detailed_info += string_format( _( "\n%s: %i more slot(s) needed." ),
2255 body_part_name_as_heading( elem.first->token, 1 ),
2256 elem.second );
2257 }
2258 popup( _( "Not enough space for bionic installation!%s" ), detailed_info );
2259 return false;
2260 }
2261
2262 if( chance_of_success >= 100 ) {
2263 if( !g->u.query_yn(
2264 _( "Are you sure you wish to install the selected bionic?" ),
2265 100 - chance_of_success ) ) {
2266 return false;
2267 }
2268 } else {
2269 if( autodoc ) {
2270 if( !g->u.query_yn(
2271 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! Continue anyway?" ),
2272 ( 100 - chance_of_success ) ) ) {
2273 return false;
2274 }
2275 } else {
2276 if( !g->u.query_yn(
2277 _( "WARNING: There is a %i percent chance of complications, such as damage or faulty installation! The following skills affect self-installation: First Aid, Electronics, and Mechanics.\n\nContinue anyway?" ),
2278 ( 100 - chance_of_success ) ) ) {
2279 return false;
2280 }
2281 }
2282 }
2283
2284 return true;
2285}
int bionic_manip_cos(float adjusted_skill, int bionic_difficulty)
Definition: bionics.cpp:1941
static const skill_id skill_mechanics("mechanics")
static const skill_id skill_computer("computer")
static const skill_id skill_firstaid("firstaid")
static const skill_id skill_electronics("electronics")
std::string body_part_name_as_heading(body_part bp, int number)
Returns the name of the body parts in a context where the name is used as a heading or title e....
Definition: bodypart.cpp:343
std::map< bodypart_id, int > bionic_installation_issues(const bionic_id &bioid) const
Definition: bionics.cpp:2555
float bionics_adjusted_skill(const skill_id &most_important_skill, const skill_id &important_skill, const skill_id &least_important_skill, int skill_level=-1)
Calculate skill for (un)installing bionics.
Definition: bionics.cpp:1898
void autodoc(player &p, const tripoint &examp)
Definition: iexamine.cpp:4814
int popup(const std::string &text, PopupFlags flags)
Definition: output.cpp:764
std::string enumerate_as_string(const _Container &values, enumeration_conjunction conj=enumeration_conjunction::and_)
Definition: output.h:637
std::vector< trait_id > canceled_mutations
Mutations/trait that are removed upon installing this CBM.
Definition: bionics.h:110
std::string name() const

References _, iexamine::autodoc(), bionic_installation_issues(), bionic_manip_cos(), bionics_adjusted_skill(), body_part_name_as_heading(), bionic_data::canceled_mutations, debugmsg, enumerate_as_string(), g, has_trait(), is_mounted(), mutation_branch::name(), popup(), query_yn(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_format(), and type.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ can_install_cbm_on_bp()

bool Character::can_install_cbm_on_bp ( const std::vector< bodypart_id > &  bps) const

Definition at line 454 of file mutation.cpp.

455{
456 bool can_install = true;
457 for( const trait_id &mut : get_mutations() ) {
458 for( const bodypart_id &bp : bps ) {
459 if( mut.obj().no_cbm_on_bp.count( bp.id() ) ) {
460 can_install = false;
461 break;
462 }
463 }
464 }
465 return can_install;
466}

References get_mutations().

Referenced by bionic_install_preset::get_denial().

◆ can_learn_by_disassembly()

bool Character::can_learn_by_disassembly ( const recipe rec) const

Definition at line 10614 of file character.cpp.

10615{
10616 return !rec.learn_by_disassembly.empty() &&
10618}
bool meets_skill_requirements(const std::map< skill_id, int > &req, const item &context=item()) const
Checks whether the character's skills meet the required.
Definition: character.cpp:3521
std::map< skill_id, int > learn_by_disassembly
Definition: recipe.h:113

References recipe::learn_by_disassembly, and meets_skill_requirements().

Referenced by crafting::complete_disassemble().

◆ can_miss_recovery()

bool Character::can_miss_recovery ( const item weap) const

Returns true if the player is able to use a miss recovery technique.

Definition at line 988 of file martialarts.cpp.

989{
990 if( !martial_arts_data->has_miss_recovery_tec( weap ) ) {
991 return false;
992 }
993
994 ma_technique tec = martial_arts_data->get_miss_recovery_tec( weap );
995
996 return tec.is_valid_character( *this );
997}
bool is_valid_character(const Character &u) const

References ma_technique::is_valid_character(), and martial_arts_data.

Referenced by melee_attack().

◆ can_mount()

bool Character::can_mount ( const monster critter) const

Definition at line 570 of file monexamine.cpp.

571{
572 const auto &avoid = get_path_avoid();
573 auto route = get_map().route( pos(), critter.pos(), get_pathfinding_settings(), avoid );
574
575 if( route.empty() ) {
576 return false;
577 }
578 return ( critter.has_flag( MF_PET_MOUNTABLE ) && critter.friendly == -1 &&
579 !critter.has_effect( effect_ai_waiting ) && !critter.has_effect( effect_ridden ) ) &&
580 ( ( critter.has_effect( effect_saddled ) && get_skill_level( skill_survival ) >= 1 ) ||
581 get_skill_level( skill_survival ) >= 4 ) && ( critter.get_size() >= ( get_size() + 1 ) &&
582 get_weight() <= critter.get_weight() * critter.get_mountable_weight_ratio() );
583}
units::mass get_weight() const override
Returns body weight plus weight of inventory and worn/wielded items.
Definition: character.cpp:3688
std::set< tripoint > get_path_avoid() const override
Returns a set of points we do not want to path through.
Definition: character.cpp:9961
m_size get_size() const override
Get size class of character.
Definition: character.cpp:575
const pathfinding_settings & get_pathfinding_settings() const override
Returns settings for pathfinding.
Definition: character.cpp:9975
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
bool has_flag(m_flag f) const override
Definition: monster.cpp:894
m_size get_size() const override
Definition: monster.cpp:2734
const tripoint & pos() const override
Definition: monster.cpp:252
units::mass get_weight() const override
Definition: monster.cpp:2739
float get_mountable_weight_ratio() const
Definition: monster.cpp:2964
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_ridden("ridden")
static const efftype_id effect_saddled("monster_saddled")
static const skill_id skill_survival("survival")
@ MF_PET_MOUNTABLE
Definition: mtype.h:165

References effect_ai_waiting, effect_ridden, effect_saddled, monster::friendly, get_map(), monster::get_mountable_weight_ratio(), get_path_avoid(), get_pathfinding_settings(), get_size(), monster::get_size(), get_skill_level(), get_weight(), monster::get_weight(), Creature::has_effect(), monster::has_flag(), MF_PET_MOUNTABLE, pos(), monster::pos(), map::route(), and skill_survival.

Referenced by talk_function::find_mount(), activity_handlers::find_mount_do_turn(), and monexamine::pet_menu().

◆ can_pick_volume() [1/2]

bool Character::can_pick_volume ( const item it) const

Definition at line 2707 of file character.cpp.

2708{
2709 inventory projected = inv;
2710 projected.add_item( it, true );
2711 return projected.volume() <= volume_capacity();
2712}
item & add_item(item newit, bool keep_invlet=false, bool assign_invlet=true, bool should_stack=true)
Definition: inventory.cpp:287
units::volume volume() const
Definition: inventory.cpp:1061

References inventory::add_item(), inv, inventory::volume(), and volume_capacity().

Referenced by avatar_funcs::add_or_drop_with_msg(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), handle_problematic_pickup(), i_add_or_drop(), npc::mug_player(), pick_one_up(), conditional_t< T >::set_can_stow_weapon(), set_item_inventory(), and starting_inv().

◆ can_pick_volume() [2/2]

bool Character::can_pick_volume ( units::volume  volume) const

Definition at line 2714 of file character.cpp.

2715{
2716 // Might not be 100% true because some items restack to a very tiny bit less
2717 // but close enough not to matter
2718 return inv.volume() + volume <= volume_capacity();
2719}

References inv, inventory::volume(), and volume_capacity().

◆ can_pick_weight() [1/2]

bool Character::can_pick_weight ( const item it,
bool  safe = true 
) const

Definition at line 2721 of file character.cpp.

2722{
2723 return can_pick_weight( it.weight(), safe );
2724}
bool can_pick_weight(const item &it, bool safe=true) const
Definition: character.cpp:2721
units::mass weight(bool include_contents=true, bool integral=false) const
Definition: item.cpp:4985
void safe(player &p, const tripoint &examp)
Attempt to crack safe through audio-feedback manual lock manipulation.
Definition: iexamine.cpp:1334

References can_pick_weight(), iexamine::safe(), and item::weight().

Referenced by avatar_funcs::add_or_drop_with_msg(), can_pick_weight(), pickup_inventory_preset::get_denial(), give_item_to(), handle_harvest(), i_add_or_drop(), npc::mug_player(), pick_one_up(), and set_item_inventory().

◆ can_pick_weight() [2/2]

bool Character::can_pick_weight ( units::mass  weight,
bool  safe = true 
) const

Definition at line 2726 of file character.cpp.

2727{
2728 if( !safe ) {
2729 // Character can carry up to four times their maximum weight
2730 return ( weight_carried() + weight <= ( has_trait( trait_DEBUG_STORAGE ) ?
2731 units::mass_max : weight_capacity() * 4 ) );
2732 } else {
2733 return ( weight_carried() + weight <= weight_capacity() );
2734 }
2735}
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
constexpr mass mass_max
Definition: units_mass.h:28

References has_trait(), units::mass_max, iexamine::safe(), trait_DEBUG_STORAGE, weight_capacity(), and weight_carried().

◆ can_reload()

bool Character::can_reload ( const item it,
const itype_id ammo = itype_id() 
) const

Whether a tool or gun is potentially reloadable (optionally considering a specific ammo)

Parameters
itThing to be reloaded
ammoif set also check item currently compatible with this specific ammo or magazine
Note
items currently loaded with a detachable magazine are considered reloadable
items with integral magazines are reloadable if free capacity permits (+/- ammo matches)

Definition at line 11069 of file character.cpp.

11070{
11071 if( !it.is_reloadable_with( ammo ) ) {
11072 return false;
11073 }
11074
11075 if( it.is_ammo_belt() ) {
11076 const auto &linkage = it.type->magazine->linkage;
11077 if( linkage && !has_charges( *linkage, 1 ) ) {
11078 return false;
11079 }
11080 }
11081
11082 return true;
11083}
bool is_reloadable_with(const itype_id &ammo) const
Returns true if this item can be reloaded with specified ammo type at this moment.
Definition: item.cpp:6881
bool is_ammo_belt() const
Definition: item.cpp:6577
cata::value_ptr< islot_magazine > magazine
Definition: itype.h:832

References has_charges(), item::is_ammo_belt(), item::is_reloadable_with(), itype::magazine, and item::type.

Referenced by can_reload_item_or_mods(), npc::find_usable_ammo(), character_funcs::list_ammo(), examine_item_menu::rate_action_reload(), ammobelt_actor::use(), and wants_to_reload().

◆ can_run()

bool Character::can_run ( )

source of truth of whether a Character can run

Definition at line 1270 of file character.cpp.

1271{
1272 return ( get_stamina() > get_stamina_max() * 0.1f ) && get_working_leg_count() >= 2;
1273}

References get_stamina(), get_stamina_max(), and get_working_leg_count().

Referenced by game::on_move_effects(), and avatar::set_movement_mode().

◆ can_swap()

ret_val< bool > Character::can_swap ( const item it) const

Check player capable of swapping the side of a worn item.

Parameters
itThing to be swapped

Definition at line 3157 of file character.cpp.

3158{
3159 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
3160 int max_layer = 2;
3161 std::vector< std::pair< body_part, int > > mod_parts;
3162 body_part bp = num_bp;
3163 bodypart_str_id bpid;
3164 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
3165 bp = static_cast< body_part >( i );
3166 bpid = convert_bp( bp );
3167 if( it.get_covered_body_parts().test( bp ) && bpid->part_side != side::BOTH ) {
3168 mod_parts.emplace_back( bp, 0 );
3169 }
3170 }
3171 for( auto &elem : worn ) {
3172 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3173 bpid = convert_bp( mod_part.first );
3174 if( elem.get_covered_body_parts().test( bpid->opposite_part->token ) &&
3175 elem.has_flag( flag_POWERARMOR_MOD ) ) {
3176 mod_part.second++;
3177 }
3178 }
3179 }
3180 for( std::pair< body_part, int > &mod_part : mod_parts ) {
3181 bpid = convert_bp( mod_part.first );
3182 if( mod_part.second >= max_layer ) {
3183 return ret_val<bool>::make_failure( _( "There is no space on the opposite side!" ) );
3184 }
3185 }
3186 }
3187
3189}
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
static const std::string flag_POWERARMOR_MOD("POWERARMOR_MOD")
side part_side
Definition: bodypart.h:128
body_part token
Definition: bodypart.h:108
bodypart_str_id opposite_part
Definition: bodypart.h:126

References _, BOTH, convert_bp(), flag_POWERARMOR_MOD(), item::get_covered_body_parts(), item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), num_bp, body_part_type::opposite_part, body_part_type::part_side, body_part_set::test(), body_part_type::token, and worn.

Referenced by change_side().

◆ can_takeoff()

ret_val< bool > Character::can_takeoff ( const item it,
const std::list< item > *  res = nullptr 
) const

Check if character is capable of taking off given item.

Parameters
itItem to be taken off
resIf set, will expect to move item into the list.

Definition at line 3022 of file character.cpp.

3023{
3024 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
3025 return &it == &wit;
3026 } );
3027
3028 if( iter == worn.end() ) {
3029 return ret_val<bool>::make_failure( !is_npc() ? _( "You are not wearing that item." ) :
3030 _( "<npcname> is not wearing that item." ) );
3031 }
3032
3033 if( res == nullptr && !get_dependent_worn_items( it ).empty() ) {
3035 _( "You can't take off power armor while wearing other power armor components." ) :
3036 _( "<npcname> can't take off power armor while wearing other power armor components." ) );
3037 }
3038 if( it.has_flag( "NO_TAKEOFF" ) ) {
3040 _( "You can't take that item off." ) :
3041 _( "<npcname> can't take that item off." ) );
3042 }
3044}
std::list< item * > get_dependent_worn_items(const item &it) const
Returns all items that must be taken off before taking off this item.
Definition: character.cpp:2426

References _, get_dependent_worn_items(), item::has_flag(), Creature::is_npc(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and worn.

Referenced by drop(), take_off_inventory_preset::get_denial(), avatar_action::plthrow(), examine_item_menu::rate_action_takeoff(), examine_item_menu::run(), takeoff(), and avatar_action::wield().

◆ can_uninstall_bionic()

bool Character::can_uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Is The uninstallation possible.

Definition at line 1962 of file bionics.cpp.

1964{
1965 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
1966 int difficulty = BIONIC_NOITEM_DIFFICULTY;
1967 if( b_id->itype().is_valid() ) {
1968 const itype *type = &*b_id->itype();
1969 if( type->bionic ) {
1970 difficulty = type->bionic->difficulty;
1971 }
1972 }
1973
1974 if( !has_bionic( b_id ) ) {
1975 popup( _( "%s don't have this bionic installed." ), disp_name() );
1976 return false;
1977 }
1978
1979 if( ( b_id == bio_reactor ) || ( b_id == bio_advreactor ) ) {
1980 if( !g->u.query_yn(
1981 _( "WARNING: Removing a reactor may leave radioactive material! Remove anyway?" ) ) ) {
1982 return false;
1983 }
1984 }
1985
1986 for( const bionic_id &bid : get_bionics() ) {
1987 if( bid->is_included( b_id ) ) {
1988 popup( _( "%s must remove the %s bionic to remove the %s." ), installer.disp_name(),
1989 bid->name, b_id->name );
1990 return false;
1991 }
1992 }
1993
1994 if( b_id == bio_eye_optic ) {
1995 popup( _( "The Telescopic Lenses are part of %s eyes now. Removing them would leave %s blind." ),
1996 disp_name( true ), disp_name() );
1997 return false;
1998 }
1999
2000 // removal of bionics adds +2 difficulty over installation
2001 float adjusted_skill;
2002 if( autodoc ) {
2003 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2006 skill_level );
2007 } else {
2008 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2011 skill_level );
2012 }
2013 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2014
2015 if( chance_of_success >= 100 ) {
2016 if( !g->u.query_yn(
2017 _( "Are you sure you wish to uninstall the selected bionic?" ),
2018 100 - chance_of_success ) ) {
2019 return false;
2020 }
2021 } else {
2022 if( !g->u.query_yn(
2023 _( "WARNING: %i percent chance of SEVERE damage to all body parts! Continue anyway?" ),
2024 ( 100 - static_cast<int>( chance_of_success ) ) ) ) {
2025 return false;
2026 }
2027 }
2028
2029 return true;
2030}
static const bionic_id bio_reactor("bio_reactor")
constexpr int BIONIC_NOITEM_DIFFICULTY
Definition: bionics.cpp:211
static const bionic_id bio_eye_optic("bio_eye_optic")
static const bionic_id bio_advreactor("bio_advreactor")
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:70
itype_id itype() const
Definition: bionics.cpp:249
Definition: itype.h:805

References _, iexamine::autodoc(), bio_advreactor, bio_eye_optic, bio_reactor, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), disp_name(), g, get_bionics(), has_bionic(), string_id< T >::is_valid(), bionic_data::itype(), bionic_data::name, popup(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, and type.

Referenced by iexamine::autodoc().

◆ can_unwield()

ret_val< bool > Character::can_unwield ( const item it) const

Check whether character is capable of unwielding given item.

Definition at line 3126 of file character.cpp.

3127{
3128 if( it.has_flag( "NO_UNWIELD" ) ) {
3129 return ret_val<bool>::make_failure( _( "You cannot unwield your %s." ), it.tname() );
3130 }
3131
3133}

References _, item::has_flag(), ret_val< T >::make_failure(), ret_val< T >::make_success(), and item::tname().

Referenced by apply_damage(), drop(), inv_dump(), examine_item_menu::run(), unwield(), and avatar_action::wield().

◆ can_use()

bool Character::can_use ( const item it,
const item context = item() 
) const

Checks if character stats and skills meet minimum requirements for the item.

Prints an appropriate message if requirements not met.

Parameters
itItem we are checking
contextoptionally override effective item when checking contextual skills

Definition at line 2737 of file character.cpp.

2738{
2739 const auto &ctx = !context.is_null() ? context : it;
2740
2741 if( !meets_requirements( it, ctx ) ) {
2742 const std::string unmet( enumerate_unmet_requirements( it, ctx ) );
2743
2744 if( &it == &ctx ) {
2745 //~ %1$s - list of unmet requirements, %2$s - item name.
2746 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s." ),
2747 _( "<npcname> needs at least %1$s to use this %2$s." ),
2748 unmet, it.tname() );
2749 } else {
2750 //~ %1$s - list of unmet requirements, %2$s - item name, %3$s - indirect item name.
2751 add_msg_player_or_npc( m_bad, _( "You need at least %1$s to use this %2$s with your %3$s." ),
2752 _( "<npcname> needs at least %1$s to use this %2$s with their %3$s." ),
2753 unmet, it.tname(), ctx.tname() );
2754 }
2755
2756 return false;
2757 }
2758
2759 return true;
2760}
std::string enumerate_unmet_requirements(const item &it, const item &context=item()) const
Returns a string of missed requirements (both stats and skills)
Definition: character.cpp:3370
bool meets_requirements(const item &it, const item &context=item()) const
Checks whether the character meets overall requirements to be able to use the item.
Definition: character.cpp:3543

References _, Creature::add_msg_player_or_npc(), enumerate_unmet_requirements(), item::is_null(), m_bad, meets_requirements(), and item::tname().

Referenced by npc_ai::best_mode_for_range(), can_use_heal_item(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_common(), and avatar_funcs::toolmod_add().

◆ can_use_floor_warmth()

bool Character::can_use_floor_warmth ( ) const

Can the player lie down and cover self with blankets etc.

Definition at line 9447 of file character.cpp.

9448{
9449 static const auto allowed_activities = std::vector<activity_id> {
9450 activity_id( "ACT_WAIT" ),
9451 activity_id( "ACT_WAIT_NPC" ),
9452 activity_id( "ACT_WAIT_STAMINA" ),
9453 activity_id( "ACT_AUTODRIVE" ),
9454 activity_id( "ACT_READ" ),
9455 activity_id( "ACT_SOCIALIZE" ),
9456 activity_id( "ACT_MEDITATE" ),
9457 activity_id( "ACT_FISH" ),
9458 activity_id( "ACT_GAME" ),
9459 activity_id( "ACT_HAND_CRANK" ),
9460 activity_id( "ACT_HEATING" ),
9461 activity_id( "ACT_VIBE" ),
9462 activity_id( "ACT_TRY_SLEEP" ),
9463 activity_id( "ACT_OPERATION" ),
9464 activity_id( "ACT_TREE_COMMUNION" ),
9465 activity_id( "ACT_EAT_MENU" ),
9466 activity_id( "ACT_CONSUME_FOOD_MENU" ),
9467 activity_id( "ACT_CONSUME_DRINK_MENU" ),
9468 activity_id( "ACT_CONSUME_MEDS_MENU" ),
9469 activity_id( "ACT_STUDY_SPELL" ),
9470 };
9471
9472 return in_sleep_state() || has_activity( allowed_activities );
9473}
string_id< activity_type > activity_id
Definition: activity_type.h:15

References has_activity(), and in_sleep_state().

Referenced by update_bodytemp().

◆ can_use_grab_break_tec()

bool Character::can_use_grab_break_tec ( const item weap) const

Returns true if the player is able to use a grab breaking technique.

Definition at line 977 of file martialarts.cpp.

978{
979 if( !has_grab_break_tec() ) {
980 return false;
981 }
982
983 ma_technique tec = martial_arts_data->get_grab_break_tec( weap );
984
985 return tec.is_valid_character( *this );
986}
bool has_grab_break_tec() const override
Returns true if the player has a grab breaking technique available.

References has_grab_break_tec(), ma_technique::is_valid_character(), and martial_arts_data.

Referenced by mattack::grab().

◆ can_use_heal_item()

bool Character::can_use_heal_item ( const item med) const

Check for mutation disallowing the use of an healing item.

Definition at line 422 of file mutation.cpp.

423{
424 const itype_id heal_id = med.typeId();
425
426 bool can_use = false;
427 bool got_restriction = false;
428
429 for( const trait_id &mut : get_mutations() ) {
430 if( !mut.obj().can_only_heal_with.empty() ) {
431 got_restriction = true;
432 }
433 if( mut.obj().can_only_heal_with.count( heal_id ) ) {
434 can_use = true;
435 break;
436 }
437 }
438 if( !got_restriction ) {
439 can_use = !med.has_flag( "CANT_HEAL_EVERYONE" );
440 }
441
442 if( !can_use ) {
443 for( const trait_id &mut : get_mutations() ) {
444 if( mut.obj().can_heal_with.count( heal_id ) ) {
445 can_use = true;
446 break;
447 }
448 }
449 }
450
451 return can_use;
452}
bool can_use(const item &it, const item &context=item()) const
Checks if character stats and skills meet minimum requirements for the item.
Definition: character.cpp:2737

References can_use(), get_mutations(), item::has_flag(), and item::typeId().

Referenced by activatable_inventory_preset::get_denial(), and heal_actor::use_healing_item().

◆ can_wear()

ret_val< bool > Character::can_wear ( const item it,
bool  with_equip_change = false 
) const

Check character capable of wearing an item.

Parameters
itThing to be worn
with_equip_changeIf true returns if it could be worn if things were taken off

Definition at line 2762 of file character.cpp.

2763{
2764 if( !it.is_armor() ) {
2765 return ret_val<bool>::make_failure( _( "Putting on a %s would be tricky." ), it.tname() );
2766 }
2767
2768 if( has_trait( trait_WOOLALLERGY ) && ( it.made_of( material_id( "wool" ) ) ||
2769 it.has_own_flag( "wooled" ) ) ) {
2770 return ret_val<bool>::make_failure( _( "Can't wear that, it's made of wool!" ) );
2771 }
2772
2773 if( it.is_filthy() && has_trait( trait_SQUEAMISH ) ) {
2774 return ret_val<bool>::make_failure( _( "Can't wear that, it's filthy!" ) );
2775 }
2776
2777 if( !it.has_flag( flag_OVERSIZE ) && !it.has_flag( flag_SEMITANGIBLE ) ) {
2778 for( const trait_id &mut : get_mutations() ) {
2779 const auto &branch = mut.obj();
2780 if( branch.conflicts_with_item( it ) ) {
2782 _( "Your %s mutation prevents you from wearing your %s." ) :
2783 _( "My %s mutation prevents me from wearing this %s." ), branch.name(),
2784 it.type_name() );
2785 }
2786 }
2787 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2788 !it.made_of( material_id( "wool" ) ) && !it.made_of( material_id( "cotton" ) ) &&
2789 !it.made_of( material_id( "nomex" ) ) && !it.made_of( material_id( "leather" ) ) &&
2791 has_trait( trait_ANTLERS ) ) ) {
2792 return ret_val<bool>::make_failure( _( "Cannot wear a helmet over %s." ),
2793 ( has_trait( trait_HORNS_POINTED ) ? _( "horns" ) :
2794 ( has_trait( trait_ANTENNAE ) ? _( "antennae" ) : _( "antlers" ) ) ) );
2795 }
2796 }
2797
2798 if( it.has_flag( flag_SPLINT ) ) {
2799 bool need_splint = false;
2800 for( const bodypart_id &bp : get_all_body_parts() ) {
2801 if( !it.covers( bp->token ) ) {
2802 continue;
2803 }
2804 if( is_limb_broken( bp ) && !worn_with_flag( flag_SPLINT, bp ) ) {
2805 need_splint = true;
2806 break;
2807 }
2808 }
2809 if( !need_splint ) {
2811 _( "You don't have any broken limbs this could help." )
2812 : _( "%s doesn't have any broken limbs this could help." ), name );
2813 }
2814 }
2815
2816 if( it.has_flag( flag_RESTRICT_HANDS ) && !has_two_arms() ) {
2817 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have enough arms to wear that." )
2818 : string_format( _( "%s doesn't have enough arms to wear that." ), name ) ) );
2819 }
2820
2821 //Everything checked after here should be something that could be solved by changing equipment
2822 if( with_equip_change ) {
2824 }
2825
2826 if( it.is_power_armor() ) {
2827 for( auto &elem : worn ) {
2828 if( ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() &&
2829 !elem.has_flag( flag_POWERARMOR_COMPATIBLE ) && !elem.is_power_armor() ) {
2830 return ret_val<bool>::make_failure( _( "Can't wear power armor over other gear!" ) );
2831 } else if( elem.has_flag( flag_POWERARMOR_EXO ) && it.has_flag( flag_POWERARMOR_EXO ) ) {
2832 return ret_val<bool>::make_failure( _( "Can't wear multiple exoskeletons!" ) );
2833 }
2834 }
2837 _( "You can only wear power armor components with power armor!" ) );
2838 }
2840 for( auto &elem : worn ) {
2841 if( elem.has_flag( flag_POWERARMOR_EXO ) &&
2842 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2843 return ret_val<bool>::make_failure( _( "Can't wear externals over an exoskeleton!" ) );
2844 } else if( elem.has_flag( flag_POWERARMOR_EXTERNAL ) &&
2845 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) {
2846 return ret_val<bool>::make_failure( _( "Can't wear externals over one another!" ) );
2847 }
2848 }
2849 }
2850 if( it.has_flag( flag_POWERARMOR_MOD ) ) {
2851 int max_layer = 2;
2852 std::vector< std::pair< body_part, int > > mod_parts;
2853 std::vector< std::pair< body_part, bool > > attachments;
2854 body_part bp = num_bp;
2855 bodypart_str_id bpid;
2856 bool lhs = false;
2857 bool rhs = false;
2858 for( std::size_t i = 0; i < static_cast< body_part >( num_bp ); ++i ) {
2859 bp = static_cast< body_part >( i );
2860 if( it.get_covered_body_parts().test( bp ) ) {
2861 mod_parts.emplace_back( bp, 0 );
2862 attachments.emplace_back( bp, false );
2863 }
2864 }
2865 for( auto &elem : worn ) {
2866 // To check if there's an external/exoskeleton for the mod to attach to.
2867 for( std::pair< body_part, bool > &attachment : attachments ) {
2868 if( elem.get_covered_body_parts().test( attachment.first ) &&
2869 ( elem.has_flag( flag_POWERARMOR_EXO ) || elem.has_flag( flag_POWERARMOR_EXTERNAL ) ) ) {
2870 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2871 attachment.second = true;
2872 } else {
2873 attachment.second = true;
2874 }
2875 }
2876 }
2877 // To check how many mods are on a given part.
2878 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2879 bpid = convert_bp( mod_part.first );
2880 if( elem.get_covered_body_parts().test( mod_part.first ) &&
2881 elem.has_flag( flag_POWERARMOR_MOD ) ) {
2882 if( elem.is_sided() && elem.get_side() == bpid->part_side ) {
2883 mod_part.second++;
2884 } else {
2885 mod_part.second++;
2886 }
2887 }
2888 }
2889 }
2890 for( std::pair< body_part, bool > &attachment : attachments ) {
2891 if( !attachment.second ) {
2892 return ret_val<bool>::make_failure( _( "Nothing to attach the mod to!" ) );
2893 }
2894 }
2895 for( std::pair< body_part, int > &mod_part : mod_parts ) {
2896 bpid = convert_bp( mod_part.first );
2897 if( static_cast< body_part >( mod_part.first ) == bp_torso ) {
2898 max_layer = 3;
2899 }
2900 if( mod_part.second >= max_layer ) {
2901 if( !it.is_sided() || bpid->part_side == side::BOTH ) {
2902 return ret_val<bool>::make_failure( _( "Can't wear any more mods on that body part!" ) );
2903 } else {
2904 if( bpid->part_side == side::LEFT ) {
2905 lhs = true;
2906 } else {
2907 rhs = true;
2908 }
2909 if( lhs && rhs ) {
2910 return ret_val<bool>::make_failure( _( "No more space for that mod!" ) );
2911 }
2912 }
2913 }
2914 }
2915 }
2916 } else {
2917 // Only headgear can be worn with power armor, except other power armor components.
2918 // You can't wear headgear if power armor helmet is already sitting on your head.
2919 for( auto &elem : worn ) {
2921 ( elem.get_covered_body_parts() & it.get_covered_body_parts() ).any() ) ) {
2922 return ret_val<bool>::make_failure( _( "Can't wear %s with power armor!" ), it.tname() );
2923 }
2924 }
2925 }
2926
2927 // Check if we don't have both hands available before wearing a briefcase, shield, etc. Also occurs if we're already wearing one.
2928 const item &weapon = primary_weapon();
2930 weapon.is_two_handed( *this ) ) ) {
2931 return ret_val<bool>::make_failure( ( is_player() ? _( "You don't have a hand free to wear that." )
2932 : string_format( _( "%s doesn't have a hand free to wear that." ), name ) ) );
2933 }
2934
2935 for( auto &i : worn ) {
2936 if( i.has_flag( flag_ONLY_ONE ) && i.typeId() == it.typeId() ) {
2937 return ret_val<bool>::make_failure( _( "Can't wear more than one %s!" ), it.tname() );
2938 }
2939 }
2940
2941 if( amount_worn( it.typeId() ) >= MAX_WORN_PER_TYPE ) {
2942 return ret_val<bool>::make_failure( _( "Can't wear %i or more %s at once." ),
2943 MAX_WORN_PER_TYPE + 1, it.tname( MAX_WORN_PER_TYPE + 1 ) );
2944 }
2945
2946 if( ( ( it.covers( bp_foot_l ) && is_wearing_shoes( side::LEFT ) ) ||
2947 ( it.covers( bp_foot_r ) && is_wearing_shoes( side::RIGHT ) ) ) &&
2948 ( !it.has_flag( flag_OVERSIZE ) || !it.has_flag( flag_OUTER ) ) && !it.has_flag( flag_SKINTIGHT ) &&
2949 !it.has_flag( flag_BELTED ) && !it.has_flag( flag_PERSONAL ) && !it.has_flag( flag_AURA ) &&
2950 !it.has_flag( flag_SEMITANGIBLE ) ) {
2951 // Checks to see if the player is wearing shoes
2952 return ret_val<bool>::make_failure( ( is_player() ? _( "You're already wearing footwear!" )
2953 : string_format( _( "%s is already wearing footwear!" ), name ) ) );
2954 }
2955
2956 if( it.covers( bp_head ) &&
2958 !it.has_flag( flag_PERSONAL ) && !it.is_power_armor() &&
2960 is_wearing_helmet() ) {
2962 ( is_player() ? _( "You can't wear that with other headgear!" )
2963 : string_format( _( "%s can't wear that with other headgear!" ), name ) ) );
2964 }
2965
2966 if( it.covers( bp_head ) && !it.has_flag( flag_SEMITANGIBLE ) &&
2968 ( head_cloth_encumbrance() + it.get_encumber( *this ) > 40 ) ) {
2969 return ret_val<bool>::make_failure( ( is_player() ? _( "You can't wear that much on your head!" )
2970 : string_format( _( "%s can't wear that much on their head!" ), name ) ) );
2971 }
2972
2974}
static const std::string flag_BELTED("BELTED")
static const trait_id trait_ANTLERS("ANTLERS")
static const trait_id trait_WOOLALLERGY("WOOLALLERGY")
static const trait_id trait_HORNS_POINTED("HORNS_POINTED")
static const std::string flag_SKINTIGHT("SKINTIGHT")
static const std::string flag_POWERARMOR_COMPATIBLE("POWERARMOR_COMPATIBLE")
static const trait_id trait_ANTENNAE("ANTENNAE")
static const std::string flag_HELMET_COMPAT("HELMET_COMPAT")
static const std::string flag_POWERARMOR_EXO("POWERARMOR_EXO")
static const std::string flag_OUTER("OUTER")
static const std::string flag_OVERSIZE("OVERSIZE")
static const std::string flag_ONLY_ONE("ONLY_ONE")
static const std::string flag_POWERARMOR_EXTERNAL("POWERARMOR_EXTERNAL")
static const std::string flag_RESTRICT_HANDS("RESTRICT_HANDS")
static const trait_id trait_SQUEAMISH("SQUEAMISH")
bool is_wearing_power_armor(bool *hasHelmet=nullptr) const
Returns true if the character is wearing power armor.
Definition: character.cpp:3808
bool is_wearing_helmet() const
Returns true if the character is wearing something occupying the helmet slot.
Definition: character.cpp:8905
int amount_worn(const itype_id &id) const
Returns the amount of item ‘type’ that is currently worn.
Definition: character.cpp:2188
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1220
int head_cloth_encumbrance() const
Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.
Definition: character.cpp:8917
bool is_wearing_shoes(const side &which_side=side::BOTH) const
Returns true if the player is wearing something on their feet that is not SKINTIGHT.
Definition: character.cpp:8876
bool is_sided() const
Returns true if item is armor and can be worn on different sides of the body.
Definition: item.cpp:807
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6423
bool is_filthy() const
Marks the item as filthy, so characters with squeamish trait can't wear it.
Definition: item.cpp:9988
std::string type_name(unsigned int quantity=1) const
Name of the item type (not the item), with proper plural.
Definition: item.cpp:9858
bool is_power_armor() const
Whether this is a power armor item.
Definition: item.cpp:5796
bool is_armor() const
Definition: item.cpp:6714
int get_encumber(const Character &) const
Returns the encumbrance value that this item has when worn by given player.
Definition: item.cpp:5802
bool is_two_handed(const Character &guy) const
Whether the character needs both hands to wield this item.
Definition: item.cpp:6414
static constexpr int MAX_WORN_PER_TYPE

References _, amount_worn(), BOTH, bp_foot_l, bp_foot_r, bp_head, bp_torso, convert_bp(), item::covers(), flag_AURA(), flag_BELTED(), flag_HELMET_COMPAT(), flag_ONLY_ONE(), flag_OUTER(), flag_OVERSIZE(), flag_PERSONAL(), flag_POWERARMOR_COMPATIBLE(), flag_POWERARMOR_EXO(), flag_POWERARMOR_EXTERNAL(), flag_POWERARMOR_MOD(), flag_RESTRICT_HANDS(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), flag_SPLINT(), Creature::get_all_body_parts(), item::get_covered_body_parts(), item::get_encumber(), get_mutations(), item::has_flag(), item::has_own_flag(), has_trait(), has_two_arms(), head_cloth_encumbrance(), item::is_armor(), item::is_filthy(), is_limb_broken(), Creature::is_player(), item::is_power_armor(), item::is_sided(), item::is_two_handed(), is_wearing_helmet(), is_wearing_power_armor(), is_wearing_shoes(), LEFT, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), MAX_WORN_PER_TYPE, name, num_bp, body_part_type::part_side, primary_weapon(), RIGHT, string_format(), body_part_set::test(), item::tname(), trait_ANTENNAE, trait_ANTLERS, trait_HORNS_POINTED, trait_SQUEAMISH, trait_WOOLALLERGY, item::type_name(), item::typeId(), wearing_something_on(), worn, and worn_with_flag().

Referenced by behavior::character_oracle_t::can_wear_warmer_clothes(), dispose_item(), wear_inventory_preset::get_denial(), give_item_to(), handle_problematic_pickup(), examine_item_menu::rate_action_wear(), spell_effect::spawn_ethereal_item(), starting_clothes(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_item().

◆ can_wield()

ret_val< bool > Character::can_wield ( const item it) const

Check whether character is capable of wielding given item.

Definition at line 3090 of file character.cpp.

3091{
3092 if( it.made_of( LIQUID ) ) {
3093 return ret_val<bool>::make_failure( _( "Can't wield spilt liquids." ) );
3094 }
3095
3096 if( get_working_arm_count() <= 0 ) {
3098 _( "You need at least one arm to even consider wielding something." ) );
3099 }
3100
3101 const item &weapon = primary_weapon();
3102 if( is_armed() && weapon.has_flag( "NO_UNWIELD" ) ) {
3103 return ret_val<bool>::make_failure( _( "The %s is preventing you from wielding the %s." ),
3105 }
3106
3107 monster *mount = mounted_creature.get();
3108 if( it.is_two_handed( *this ) && ( !has_two_arms() || worn_with_flag( flag_RESTRICT_HANDS ) ) &&
3109 !( is_mounted() && mount->has_flag( MF_RIDEABLE_MECH ) &&
3110 mount->type->mech_weapon && it.typeId() == mount->type->mech_weapon ) ) {
3113 _( "Something you are wearing hinders the use of both hands." ) );
3114 } else if( it.has_flag( "ALWAYS_TWOHAND" ) ) {
3115 return ret_val<bool>::make_failure( _( "The %s can't be wielded with only one arm." ),
3116 it.tname() );
3117 } else {
3118 return ret_val<bool>::make_failure( _( "You are too weak to wield %s with only one arm." ),
3119 it.tname() );
3120 }
3121 }
3122
3124}
int get_working_arm_count() const
Returns the number of functioning arms.
Definition: character.cpp:1227
bool is_armed() const
Returns true if the character is wielding something.
Definition: melee.cpp:206
const mtype * type
Definition: monster.h:478
@ LIQUID
Definition: enums.h:175
std::string fmt_wielded_weapon(const Character &who)
Get the formatted name of the currently wielded item (if any) with current gun mode (if gun)
itype_id mech_weapon
If this monster is a rideable mech with built-in weapons, this is the weapons id.
Definition: mtype.h:369

References _, flag_RESTRICT_HANDS(), character_funcs::fmt_wielded_weapon(), get_working_arm_count(), item::has_flag(), monster::has_flag(), has_two_arms(), is_armed(), is_mounted(), item::is_two_handed(), LIQUID, item::made_of(), ret_val< T >::make_failure(), ret_val< T >::make_success(), mtype::mech_weapon, MF_RIDEABLE_MECH, mounted_creature, primary_weapon(), item::tname(), monster::type, item::typeId(), and worn_with_flag().

Referenced by apply_damage(), find_best_bench(), weapon_inventory_preset::get_denial(), pick_one_up(), character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ cancel_activity()

void Character::cancel_activity ( )

Definition at line 9239 of file character.cpp.

9240{
9241 activity.canceled( *this );
9242 if( has_activity( ACT_MOVE_ITEMS ) && is_hauling() ) {
9243 stop_hauling();
9244 }
9245 if( has_activity( ACT_TRY_SLEEP ) ) {
9246 remove_value( "sleep_query" );
9247 }
9248 // Clear any backlog items that aren't auto-resume.
9249 for( auto backlog_item = backlog.begin(); backlog_item != backlog.end(); ) {
9250 if( backlog_item->auto_resume ) {
9251 backlog_item++;
9252 } else {
9253 backlog_item = backlog.erase( backlog_item );
9254 }
9255 }
9256 // act wait stamina interrupts an ongoing activity.
9257 // and automatically puts auto_resume = true on it
9258 // we don't want that to persist if there is another interruption.
9259 // and player moves elsewhere.
9260 if( has_activity( ACT_WAIT_STAMINA ) && !backlog.empty() &&
9261 backlog.front().auto_resume ) {
9262 backlog.front().auto_resume = false;
9263 }
9264 if( activity && activity.is_suspendable() ) {
9265 backlog.push_front( activity );
9266 }
9267 sfx::end_activity_sounds(); // kill activity sounds when canceled
9269}
static const activity_id ACT_TRY_SLEEP("ACT_TRY_SLEEP")
static const activity_id ACT_MOVE_ITEMS("ACT_MOVE_ITEMS")
static const activity_id ACT_WAIT_STAMINA("ACT_WAIT_STAMINA")
bool is_hauling() const
Definition: character.cpp:9191
void stop_hauling()
Definition: character.cpp:9182
void canceled(Character &who)
Performs activity-specific cleanup when Character::cancel_activity() is called.
bool is_suspendable() const
If this returns true, the action can be continued without starting from scratch again (see player::ba...
void end_activity_sounds()
Definition: sounds.cpp:1604

References ACT_MOVE_ITEMS, ACT_TRY_SLEEP, ACT_WAIT_STAMINA, activity, backlog, player_activity::canceled(), sfx::end_activity_sounds(), has_activity(), is_hauling(), player_activity::is_suspendable(), Creature::remove_value(), and stop_hauling().

Referenced by activity_on_turn_move_loot(), activity_on_turn_wear(), activity_handlers::adv_inventory_do_turn(), activity_handlers::armor_layers_do_turn(), activity_handlers::build_do_turn(), player::can_continue_craft(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), activity_handlers::craft_do_turn(), autodrive_activity_actor::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), pickup_activity_actor::do_turn(), avatar_action::eat(), fall_asleep(), game::forced_door_closing(), item::handle_craft_failure(), mattack::pull_metal_weapon(), npc::reboot(), DefaultRemovePartHandler::removed(), show_armor_layers_ui(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), stop_hauling(), and npc::talk_to_u().

◆ cancel_stashed_activity()

void Character::cancel_stashed_activity ( )

◆ change_side() [1/2]

bool Character::change_side ( item it,
bool  interactive = true 
)

Swap side on which item is worn; returns false on fail.

If interactive is false, don't alert player or drain moves

Definition at line 3720 of file character.cpp.

3721{
3722 const auto ret = can_swap( it );
3723 if( !ret.success() ) {
3724 if( interactive ) {
3725 add_msg_if_player( m_info, "%s", ret.c_str() );
3726 }
3727 return false;
3728 }
3729
3730 if( !it.swap_side() ) {
3731 if( interactive ) {
3733 _( "You cannot swap the side on which your %s is worn." ),
3734 _( "<npcname> cannot swap the side on which their %s is worn." ),
3735 it.tname() );
3736 }
3737 return false;
3738 }
3739
3740 if( interactive ) {
3741 add_msg_player_or_npc( m_info, _( "You swap the side on which your %s is worn." ),
3742 _( "<npcname> swaps the side on which their %s is worn." ),
3743 it.tname() );
3744 }
3745
3746 mod_moves( -250 );
3748
3749 return true;
3750}
ret_val< bool > can_swap(const item &it) const
Check player capable of swapping the side of a worn item.
Definition: character.cpp:3157
bool swap_side()
Swap the side on which the item is worn.
Definition: item.cpp:835

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), can_swap(), m_info, Creature::mod_moves(), reset_encumbrance(), cata::hash64_detail::ret, item::swap_side(), and item::tname().

Referenced by npc::adjust_worn(), change_side(), examine_item_menu::run(), and show_armor_layers_ui().

◆ change_side() [2/2]

bool Character::change_side ( item_location loc,
bool  interactive = true 
)

Definition at line 3752 of file character.cpp.

3753{
3754 if( !loc || !is_worn( *loc ) ) {
3755 if( interactive ) {
3757 _( "You are not wearing that item." ),
3758 _( "<npcname> isn't wearing that item." ) );
3759 }
3760 return false;
3761 }
3762
3763 return change_side( *loc, interactive );
3764}
bool is_worn(const item &thing) const
Definition: character.h:1097
bool change_side(item &it, bool interactive=true)
Swap side on which item is worn; returns false on fail.
Definition: character.cpp:3720

References _, Creature::add_msg_player_or_npc(), change_side(), is_worn(), and m_info.

◆ check_and_recover_morale()

bool Character::check_and_recover_morale ( )

Checks permanent morale for consistency and recovers it when an inconsistency is found.

Definition at line 9134 of file character.cpp.

9135{
9136 player_morale test_morale;
9137
9138 for( const item &wit : worn ) {
9139 test_morale.on_item_wear( wit );
9140 }
9141
9142 for( const trait_id &mut : get_mutations() ) {
9143 test_morale.on_mutation_gain( mut );
9144 }
9145
9146 for( const auto &elem : *effects ) {
9147 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
9148 const effect &e = _effect_it.second;
9149 if( !e.is_removed() ) {
9150 test_morale.on_effect_int_change( e.get_id(), e.get_intensity(), e.get_bp() );
9151 }
9152 }
9153 }
9154
9155 test_morale.on_stat_change( "kcal", get_stored_kcal() );
9156 test_morale.on_stat_change( "thirst", get_thirst() );
9157 test_morale.on_stat_change( "fatigue", get_fatigue() );
9158 test_morale.on_stat_change( "pain", get_pain() );
9159 test_morale.on_stat_change( "pkill", get_painkiller() );
9160 test_morale.on_stat_change( "perceived_pain", get_perceived_pain() );
9161
9163
9164 if( !morale->consistent_with( test_morale ) ) {
9165 *morale = player_morale( test_morale ); // Recover consistency
9166 add_msg( m_debug, "%s morale was recovered.", disp_name( true ) );
9167 return false;
9168 }
9169
9170 return true;
9171}
int get_fatigue() const
Definition: character.cpp:4480
int get_thirst() const
Definition: character.cpp:4352
void apply_persistent_morale()
Ensures persistent morale effects are up-to-date.
Definition: character.cpp:9013
pimpl< effects_map > effects
Definition: creature.h:820
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:308
int get_intensity() const
Returns the intensity of an effect.
Definition: effect.cpp:849
const bodypart_str_id & get_bp() const
Returns the targeted body_part of the effect.
Definition: effect.cpp:835
bool is_removed() const
Returns if the effect is disabled and set up for removal.
Definition: effect.h:249
void on_item_wear(const item &it)
Definition: morale.cpp:935
void on_stat_change(const std::string &stat, int value)
Definition: morale.cpp:927
void on_effect_int_change(const efftype_id &eid, int intensity, const bodypart_str_id &bp=bodypart_str_id::NULL_ID())
Definition: morale.cpp:974
void on_mutation_gain(const trait_id &mid)
Definition: morale.cpp:917

References add_msg(), apply_persistent_morale(), disp_name(), Creature::effects, effect::get_bp(), get_fatigue(), effect::get_id(), effect::get_intensity(), get_mutations(), Creature::get_pain(), get_painkiller(), get_perceived_pain(), get_stored_kcal(), get_thirst(), effect::is_removed(), m_debug, morale, player_morale::on_effect_int_change(), player_morale::on_item_wear(), player_morale::on_mutation_gain(), player_morale::on_stat_change(), and worn.

Referenced by process_turn().

◆ check_item_encumbrance_flag()

void Character::check_item_encumbrance_flag ( )

Checks worn items for the "RESET_ENCUMBRANCE" flag, which indicates that encumbrance may have changed and require recalculating.

Definition at line 1768 of file character.cpp.

1769{
1770 bool update_required = check_encumbrance;
1771 for( auto &i : worn ) {
1772 if( !update_required && i.encumbrance_update_ ) {
1773 update_required = true;
1774 }
1775 i.encumbrance_update_ = false;
1776 }
1777
1778 if( update_required ) {
1780 }
1781}
bool check_encumbrance
Definition: character.h:2257

References check_encumbrance, reset_encumbrance(), and worn.

◆ check_mount_is_spooked()

bool Character::check_mount_is_spooked ( )

Definition at line 1041 of file character.cpp.

1042{
1043 if( !is_mounted() ) {
1044 return false;
1045 }
1046 // chance to spook per monster nearby:
1047 // base 1% per turn.
1048 // + 1% per square closer than 15 distanace. (1% - 15%)
1049 // * 2 if hostile monster is bigger than or same size as mounted creature.
1050 // -0.25% per point of dexterity (low -1%, average -2%, high -3%, extreme -3.5%)
1051 // -0.1% per point of strength ( low -0.4%, average -0.8%, high -1.2%, extreme -1.4% )
1052 // / 2 if horse has full tack and saddle.
1053 // Monster in spear reach monster and average stat (8) player on saddled horse, 14% -2% -0.8% / 2 = ~5%
1054 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1055 const m_size mount_size = mounted_creature->get_size();
1056 const bool saddled = mounted_creature->has_effect( effect_saddled );
1057 for( const monster &critter : g->all_monsters() ) {
1058 double chance = 1.0;
1059 Attitude att = critter.attitude_to( *this );
1060 // actually too close now - horse might spook.
1061 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 10 ) {
1062 chance += 10 - rl_dist( pos(), critter.pos() );
1063 if( critter.get_size() >= mount_size ) {
1064 chance *= 2;
1065 }
1066 chance -= 0.25 * get_dex();
1067 chance -= 0.1 * get_str();
1068 if( saddled ) {
1069 chance /= 2;
1070 }
1071 chance = std::max( 1.0, chance );
1072 if( x_in_y( chance, 100.0 ) ) {
1074 return true;
1075 }
1076 }
1077 }
1078 }
1079 return false;
1080}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
static const efftype_id effect_saddled("monster_saddled")
virtual int get_dex() const
Definition: character.cpp:4093
void forced_dismount()
Definition: character.cpp:1087
Attitude
Simplified attitude towards any creature: hostile - hate, want to kill, etc.
Definition: creature.h:166
m_size
Definition: creature.h:57

References Creature::A_HOSTILE, effect_saddled, forced_dismount(), g, get_dex(), get_str(), HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), sees(), and x_in_y().

Referenced by game::do_turn().

◆ check_mount_will_move()

bool Character::check_mount_will_move ( const tripoint dest_loc)

Definition at line 1023 of file character.cpp.

1024{
1025 if( !is_mounted() ) {
1026 return true;
1027 }
1028 if( mounted_creature && mounted_creature->type->has_fear_trigger( mon_trigger::HOSTILE_CLOSE ) ) {
1029 for( const monster &critter : g->all_monsters() ) {
1030 Attitude att = critter.attitude_to( *this );
1031 if( att == A_HOSTILE && sees( critter ) && rl_dist( pos(), critter.pos() ) <= 15 &&
1032 rl_dist( dest_loc, critter.pos() ) < rl_dist( pos(), critter.pos() ) ) {
1033 add_msg_if_player( _( "You fail to budge your %s!" ), mounted_creature->get_name() );
1034 return false;
1035 }
1036 }
1037 }
1038 return true;
1039}

References _, Creature::A_HOSTILE, Creature::add_msg_if_player(), g, HOSTILE_CLOSE, is_mounted(), mounted_creature, pos(), rl_dist(), and sees().

Referenced by avatar_action::move().

◆ check_needs_extremes()

void Character::check_needs_extremes ( )

Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.

Intelligence slightly decreases occurrence of short naps when dead tired Intelligence slightly decreases occurrence of short naps when exhausted Perception slightly decreases occurrence of short naps when sleep deprived Perception slightly increases resilience against passing out from sleep deprivation

Definition at line 5007 of file character.cpp.

5008{
5009 // Check if we've overdosed... in any deadly way.
5010 if( get_stim() > 250 ) {
5011 add_msg_if_player( m_bad, _( "You have a sudden heart attack!" ) );
5012 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
5013 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5014 } else if( get_stim() < -200 || get_painkiller() > 240 ) {
5015 add_msg_if_player( m_bad, _( "Your breathing stops completely." ) );
5016 g->events().send<event_type::dies_from_drug_overdose>( getID(), efftype_id() );
5017 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5018 } else if( has_effect( effect_jetinjector ) && get_effect_dur( effect_jetinjector ) > 40_minutes ) {
5019 if( !( has_trait( trait_NOPAIN ) ) ) {
5020 add_msg_if_player( m_bad, _( "Your heart spasms painfully and stops." ) );
5021 } else {
5022 add_msg_if_player( _( "Your heart spasms and stops." ) );
5023 }
5025 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5026 } else if( get_effect_dur( effect_adrenaline ) > 50_minutes ) {
5027 add_msg_if_player( m_bad, _( "Your heart spasms and stops." ) );
5029 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5030 } else if( get_effect_int( effect_drunk ) > 4 ) {
5031 add_msg_if_player( m_bad, _( "Your breathing slows down to a stop." ) );
5033 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5034 }
5035
5036 // check if we've starved
5037 if( is_player() ) {
5038 if( get_stored_kcal() <= 0 ) {
5039 add_msg_if_player( m_bad, _( "You have starved to death." ) );
5040 g->events().send<event_type::dies_of_starvation>( getID() );
5041 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5042 } else if( calendar::once_every( 6_hours ) ) {
5043 std::string category;
5044 if( get_kcal_percent() < 0.1f ) {
5045 category = "empty_starving";
5046 } else if( get_kcal_percent() < 0.25f ) {
5047 category = "empty_emaciated";
5048 } else if( get_kcal_percent() < 0.5f ) {
5049 category = "empty_malnutrition";
5050 } else if( get_kcal_percent() < 0.7f ) {
5051 category = "empty_low_cal";
5052 }
5053 if( !category.empty() ) {
5054 const translation message = SNIPPET.random_from_category( category ).value_or( translation() );
5056 }
5057
5058 }
5059 }
5060
5061 // Check if we're dying of thirst
5063 if( get_thirst() >= thirst_levels::dead ) {
5064 add_msg_if_player( m_bad, _( "You have died of dehydration." ) );
5065 g->events().send<event_type::dies_of_thirst>( getID() );
5066 set_part_hp_cur( bodypart_id( "torso" ), 0 );
5067 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.333f ) &&
5068 calendar::once_every( 30_minutes ) ) {
5069 add_msg_if_player( m_warning, _( "Even your eyes feel dry…" ) );
5070 } else if( get_thirst() >= lerp( +thirst_levels::parched, +thirst_levels::dead, 0.666f ) &&
5071 calendar::once_every( 30_minutes ) ) {
5072 add_msg_if_player( m_warning, _( "You are THIRSTY!" ) );
5073 } else if( calendar::once_every( 30_minutes ) ) {
5074 add_msg_if_player( m_warning, _( "Your mouth feels so dry…" ) );
5075 }
5076 }
5077
5078 // Check if we're falling asleep, unless we're sleeping
5081 add_msg_if_player( m_bad, _( "Survivor sleep now." ) );
5083 mod_fatigue( -10 );
5084 fall_asleep();
5085 } else if( get_fatigue() >= 800 && calendar::once_every( 30_minutes ) ) {
5086 add_msg_if_player( m_warning, _( "Anywhere would be a good place to sleep…" ) );
5087 } else if( calendar::once_every( 30_minutes ) ) {
5088 add_msg_if_player( m_warning, _( "You feel like you haven't slept in days." ) );
5089 }
5090 }
5091
5092 // Even if we're not Exhausted, we really should be feeling lack/sleep earlier
5093 // Penalties start at Dead Tired and go from there
5095 if( get_fatigue() >= 700 ) {
5096 if( calendar::once_every( 30_minutes ) ) {
5097 add_msg_if_player( m_warning, _( "You're too physically tired to stop yawning." ) );
5098 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5099 }
5100 /** @EFFECT_INT slightly decreases occurrence of short naps when dead tired */
5101 if( one_in( 50 + int_cur ) ) {
5102 fall_asleep( 30_seconds );
5103 }
5104 } else if( get_fatigue() >= fatigue_levels::exhausted ) {
5105 if( calendar::once_every( 30_minutes ) ) {
5106 add_msg_if_player( m_warning, _( "How much longer until bedtime?" ) );
5107 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5108 }
5109 /** @EFFECT_INT slightly decreases occurrence of short naps when exhausted */
5110 if( one_in( 100 + int_cur ) ) {
5111 fall_asleep( 30_seconds );
5112 }
5113 } else if( get_fatigue() >= fatigue_levels::dead_tired && calendar::once_every( 30_minutes ) ) {
5114 add_msg_if_player( m_warning, _( "*yawn* You should really get some sleep." ) );
5115 add_effect( effect_lack_sleep, 30_minutes + 1_turns );
5116 }
5117 }
5118
5119 // Sleep deprivation kicks in if lack of sleep is avoided with stimulants or otherwise for long periods of time
5121 float sleep_deprivation_pct = sleep_deprivation / static_cast<float>
5123
5125 calendar::once_every( 60_minutes ) &&
5129 _( "Your mind feels tired. It's been a while since you've slept well." ) );
5130 mod_fatigue( 1 );
5133 _( "Your mind feels foggy from lack of good sleep, and your eyes keep trying to close against your will." ) );
5134 mod_fatigue( 5 );
5135
5136 if( one_in( 10 ) ) {
5137 mod_healthy_mod( -1, 0 );
5138 }
5141 _( "Your mind feels weary, and you dread every wakeful minute that passes. You crave sleep, and feel like you're about to collapse." ) );
5142 mod_fatigue( 10 );
5143
5144 if( one_in( 5 ) ) {
5145 mod_healthy_mod( -2, -20 );
5146 }
5149 _( "You haven't slept decently for so long that your whole body is screaming for mercy. It's a miracle that you're still awake, but it just feels like a curse now." ) );
5150 mod_fatigue( 40 );
5151
5152 mod_healthy_mod( -5, -50 );
5153 }
5154 // else you pass out for 20 hours, guaranteed
5155
5156 // Microsleeps are slightly worse if you're sleep deprived, but not by much. (chance: 1 in (75 + per_cur) at minor sleep deprivation)
5157 // Note: these can coexist with fatigue-related microsleeps
5158 /** @EFFECT_PER slightly decreases occurrence of short naps when sleep deprived */
5159 if( one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 75 + get_per() ) ) ) {
5160 fall_asleep( 30_seconds );
5161 }
5162
5163
5166 /** @EFFECT_PER slightly increases resilience against passing out from sleep deprivation */
5167 one_in( static_cast<int>( ( 1.0f - sleep_deprivation_pct ) * 100 ) + get_per() ) ) ) ) {
5169 _( "Your body collapses due to sleep deprivation, your neglected fatigue rushing back all at once, and you pass out on the spot." )
5170 , _( "<npcname> collapses to the ground from exhaustion." ) );
5172 set_fatigue( static_cast<int>( fatigue_levels::exhausted ) );
5173 }
5174
5176 fall_asleep( 20_hours );
5178 fall_asleep( 16_hours );
5179 } else {
5180 fall_asleep( 12_hours );
5181 }
5182 }
5183 }
5184}
constexpr T lerp(const T &min, const T &max, float t)
Linear interpolation: returns first argument if t is 0, second if t is 1, otherwise proportional to t...
Definition: cata_utility.h:159
static const efftype_id effect_lack_sleep("lack_sleep")
static const efftype_id effect_drunk("drunk")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_meth("meth")
static const efftype_id effect_jetinjector("jetinjector")
static const trait_id trait_NOPAIN("NOPAIN")
float get_kcal_percent() const
Definition: character.cpp:4347
virtual void set_fatigue(int nfatigue)
Definition: character.cpp:4465
void fall_asleep()
Adds "sleep" to the player.
Definition: character.cpp:9279
virtual void mod_fatigue(int nfatigue)
Definition: character.cpp:4455
int get_stim() const
Definition: character.cpp:7060
virtual void mod_healthy_mod(int nhealthy_mod, int cap)
Definition: character.cpp:4283
int get_sleep_deprivation() const
Definition: character.cpp:4485
virtual int get_per() const
Definition: character.cpp:4097
void set_part_hp_cur(const bodypart_id &id, int set)
Definition: creature.cpp:1622
time_duration get_effect_dur(const efftype_id &eff_id, body_part bp=num_bp) const
Returns the duration of the matching effect.
Definition: creature.cpp:1282
std::optional< translation > random_from_category(const std::string &cat) const
Returns a random snippet out of the given category.
Class for storing translation context and raw string for deferred translation.
Definition: translations.h:152
@ m_warning
Definition: enums.h:264
@ falls_asleep_from_exhaustion
@ dies_from_drug_overdose
@ dies_of_starvation
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
std::string message
Definition: mapgen.cpp:420
snippet_library SNIPPET

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dead, dead_tired, dies_from_drug_overdose, dies_of_starvation, dies_of_thirst, effect_adrenaline, effect_drunk, effect_jetinjector, effect_lack_sleep, effect_meth, efftype_id, exhausted, fall_asleep(), falls_asleep_from_exhaustion, g, Creature::get_effect_dur(), Creature::get_effect_int(), get_fatigue(), get_kcal_percent(), get_painkiller(), get_per(), get_sleep_deprivation(), get_stim(), get_stored_kcal(), get_thirst(), getID(), harmless, Creature::has_effect(), has_trait(), in_sleep_state(), int_cur, Creature::is_player(), lerp(), m_bad, m_warning, major, massive, mapgen_defer::message, minor, mod_fatigue(), mod_healthy_mod(), calendar::once_every(), one_in(), parched, snippet_library::random_from_category(), serious, set_fatigue(), Creature::set_part_hp_cur(), sleep_deprivation, SNIPPET, and trait_NOPAIN.

Referenced by update_body().

◆ check_outbounds_activity()

bool Character::check_outbounds_activity ( const player_activity act,
bool  check_only = false 
)

Definition at line 931 of file character.cpp.

932{
933 map &here = get_map();
934 if( ( act.placement != tripoint_zero && act.placement != tripoint_min &&
935 !here.inbounds( here.getlocal( act.placement ) ) ) || ( !act.coords.empty() &&
936 !here.inbounds( here.getlocal( act.coords.back() ) ) ) ) {
937 if( is_npc() && !check_only ) {
938 // stash activity for when reloaded.
940 if( !backlog.empty() ) {
942 }
944 }
946 "npc %s at pos %d %d, activity target is not inbounds at %d %d therefore activity was stashed",
947 disp_name(), pos().x, pos().y, act.placement.x, act.placement.y );
948 return true;
949 }
950 return false;
951}
static constexpr tripoint tripoint_zero
Definition: point.h:259
static constexpr tripoint tripoint_min
Definition: point.h:304

References act, activity, add_msg(), backlog, disp_name(), get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), Creature::is_npc(), m_debug, pos(), stashed_outbounds_activity, stashed_outbounds_backlog, tripoint_min, and tripoint_zero.

Referenced by player_activity::do_turn(), and npc::move().

◆ clairvoyance()

int Character::clairvoyance ( ) const

Returns the distance the player can see through walls.

Definition at line 689 of file character.cpp.

690{
692 return MAX_CLAIRVOYANCE;
693 }
694
696 return 8;
697 }
698
700 return 3;
701 }
702
703 // 0 would mean we have clairvoyance of own tile
704 return -1;
705}
@ VISION_CLAIRVOYANCE_PLUS
@ VISION_CLAIRVOYANCE_SUPER
std::bitset< NUM_VISION_MODES > vision_mode_cache
Definition: character.h:2178

References VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, and vision_mode_cache.

Referenced by sees().

◆ clear_bionics()

void Character::clear_bionics ( )

Remove all bionics.

Definition at line 2709 of file bionics.cpp.

2710{
2711 my_bionics->clear();
2712}

References my_bionics.

◆ clear_destination()

◆ clear_destination_activity()

void Character::clear_destination_activity ( )

Definition at line 958 of file character.cpp.

959{
961}
player_activity destination_activity
Definition: character.h:2242

References destination_activity.

Referenced by clear_destination().

◆ clear_miss_reasons()

void Character::clear_miss_reasons ( )

Clears the list of reasons for why the player would miss a melee attack.

Definition at line 385 of file melee.cpp.

386{
387 melee_miss_reasons.clear();
388}

References melee_miss_reasons.

Referenced by process_turn().

◆ clear_morale()

void Character::clear_morale ( )

Definition at line 9124 of file character.cpp.

9125{
9126 morale->clear();
9127}

References morale.

◆ clear_mutations()

void Character::clear_mutations ( )

Empties the trait and mutations lists.

Definition at line 2885 of file newcharacter.cpp.

2886{
2887 while( !my_traits.empty() ) {
2888 toggle_trait( *my_traits.begin() );
2889 }
2890 while( !my_mutations.empty() ) {
2891 unset_mutation( my_mutations.begin()->first );
2892 }
2893 cached_mutations.clear();
2894}
void toggle_trait(const trait_id &)
Toggles a trait on the player and in their mutation list.
Definition: mutation.cpp:125
std::vector< const mutation_branch * > cached_mutations
Pointers to mutation branches in my_mutations.
Definition: character.h:2164
void unset_mutation(const trait_id &)
Definition: mutation.cpp:165
std::unordered_set< trait_id > my_traits
Contains mutation ids of the base traits.
Definition: character.h:2160

References cached_mutations, my_mutations, my_traits, toggle_trait(), and unset_mutation().

Referenced by npc::randomize(), and reset_scenario().

◆ clear_npc_ai_info_cache()

void Character::clear_npc_ai_info_cache ( npc_ai_info  key) const

◆ clear_skills()

void Character::clear_skills ( )

Clear the skills map, setting all levels to 0.

Definition at line 2896 of file newcharacter.cpp.

2897{
2898 for( auto &sk : *_skills ) {
2899 sk.second.level( 0 );
2900 }
2901}
pimpl< SkillLevelMap > _skills
Character skills.
Definition: character.h:2171

References _skills.

Referenced by reset_scenario().

◆ compute_effective_nutrients()

nutrients Character::compute_effective_nutrients ( const item comest) const

Definition at line 335 of file consumption.cpp.

336{
337 if( !comest.is_comestible() ) {
338 return {};
339 }
340
341 // if item has components, will derive calories from that instead.
342 if( !comest.components.empty() && !comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
343 nutrients tally{};
344 for( const item &component : comest.components ) {
345 nutrients component_value =
347 if( component.has_flag( flag_BYPRODUCT ) ) {
348 tally -= component_value;
349 } else {
350 tally += component_value;
351 }
352 }
353 return tally / comest.recipe_charges;
354 } else {
355 return compute_default_effective_nutrients( comest, *this );
356 }
357}
std::list< item > components
Definition: item.h:2172
int recipe_charges
Definition: item.h:2212
static nutrients compute_default_effective_nutrients(const item &comest, const Character &you, const cata::flat_set< std::string > &extra_flags={})
static const std::string flag_NUTRIENT_OVERRIDE("NUTRIENT_OVERRIDE")
static const std::string flag_BYPRODUCT("BYPRODUCT")

References item::components, compute_default_effective_nutrients(), compute_effective_nutrients(), flag_BYPRODUCT(), flag_NUTRIENT_OVERRIDE(), item::has_flag(), item::is_comestible(), and item::recipe_charges.

Referenced by can_eat(), comestible_inventory_preset::comestible_inventory_preset(), compute_effective_nutrients(), consume_effects(), eat(), item::food_info(), nutrition_for(), and will_eat().

◆ compute_nutrient_range() [1/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const item comest,
const recipe_id recipe_i,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Get calorie & vitamin contents for a comestible, taking into account character traits.

Get range of possible nutrient content, for a particular recipe, depending on choice of ingredients

Definition at line 361 of file consumption.cpp.

364{
365 if( !comest.is_comestible() ) {
366 return {};
367 }
368
369 // if item has components, will derive calories from that instead.
370 if( comest.has_flag( flag_NUTRIENT_OVERRIDE ) ) {
372 return { result, result };
373 }
374
375 nutrients tally_min;
376 nutrients tally_max;
377
378 const recipe &rec = *recipe_i;
379
380 cata::flat_set<std::string> our_extra_flags = extra_flags;
381
382 if( rec.hot_result() || rec.dehydrate_result() ) {
383 our_extra_flags.insert( flag_COOKED );
384 }
385
386 const requirement_data requirements = rec.simple_requirements();
387 const requirement_data::alter_item_comp_vector &component_requirements =
388 requirements.get_components();
389
390 for( const std::vector<item_comp> &component_options : component_requirements ) {
391 nutrients this_min;
392 nutrients this_max;
393 bool first = true;
394 for( const item_comp &component_option : component_options ) {
395 std::pair<nutrients, nutrients> component_option_range =
396 compute_nutrient_range( component_option.type, our_extra_flags );
397 component_option_range.first *= component_option.count;
398 component_option_range.second *= component_option.count;
399
400 if( first ) {
401 std::tie( this_min, this_max ) = component_option_range;
402 first = false;
403 } else {
404 this_min.min_in_place( component_option_range.first );
405 this_max.max_in_place( component_option_range.second );
406 }
407 }
408 tally_min += this_min;
409 tally_max += this_max;
410 }
411
412 for( const std::pair<const itype_id, int> &byproduct : rec.byproducts ) {
413 item byproduct_it( byproduct.first, calendar::turn, byproduct.second );
414 nutrients byproduct_nutr = compute_default_effective_nutrients( byproduct_it, *this );
415 tally_min -= byproduct_nutr;
416 tally_max -= byproduct_nutr;
417 }
418
419 int charges = comest.count();
420 return { tally_min / charges, tally_max / charges };
421}
std::pair< nutrients, nutrients > compute_nutrient_range(const item &, const recipe_id &, const cata::flat_set< std::string > &extra_flags={}) const
Get calorie & vitamin contents for a comestible, taking into account character traits.
iterator insert(iterator, const value_type &value)
Definition: flat_set.h:151
int count() const
If count_by_charges(), returns charges, otherwise 1.
Definition: item.cpp:6020
Definition: recipe.h:35
const requirement_data & simple_requirements() const
Fetch combined requirement data (inline and via "using" syntax).
Definition: recipe.h:69
bool dehydrate_result() const
Definition: recipe.cpp:837
bool hot_result() const
Definition: recipe.cpp:810
std::map< itype_id, int > byproducts
Definition: recipe.h:107
static const std::string flag_COOKED("COOKED")
void min_in_place(const nutrients &r)
Replace the values here with the minimum (or maximum) of themselves and the corresponding values take...
Definition: stomach.cpp:12
void max_in_place(const nutrients &r)
Definition: stomach.cpp:29
The *_vector members represent list of alternatives requirements: alter_tool_comp_vector = { * { { a,...
Definition: requirements.h:215
const alter_item_comp_vector & get_components() const
std::vector< std::vector< item_comp > > alter_item_comp_vector
Definition: requirements.h:223

References recipe::byproducts, compute_default_effective_nutrients(), compute_nutrient_range(), item::count(), recipe::dehydrate_result(), flag_COOKED(), flag_NUTRIENT_OVERRIDE(), requirement_data::get_components(), item::has_flag(), recipe::hot_result(), cata::flat_set< T, Compare, Data >::insert(), item::is_comestible(), nutrients::max_in_place(), nutrients::min_in_place(), recipe::simple_requirements(), and calendar::turn.

Referenced by compute_nutrient_range(), and item::food_info().

◆ compute_nutrient_range() [2/2]

std::pair< nutrients, nutrients > Character::compute_nutrient_range ( const itype_id comest_id,
const cata::flat_set< std::string > &  extra_flags = {} 
) const

Same, but across arbitrary recipes.

Definition at line 425 of file consumption.cpp.

427{
428 const itype *comest = &*comest_id;
429 if( !comest->comestible ) {
430 return {};
431 }
432
433 item comest_it( comest, calendar::turn, 1 );
434 // The default nutrients are always a possibility
435 nutrients min_nutr = compute_default_effective_nutrients( comest_it, *this, extra_flags );
436
437 if( comest->has_flag( flag_NUTRIENT_OVERRIDE ) ||
438 recipe_dict.is_item_on_loop( comest->get_id() ) ) {
439 return { min_nutr, min_nutr };
440 }
441
442 nutrients max_nutr = min_nutr;
443
444 for( const recipe_id &rec : comest->recipes ) {
445 nutrients this_min;
446 nutrients this_max;
447
448 item result_it = rec->create_result();
449 if( result_it.contents.num_item_stacks() == 1 ) {
450 const item alt_result = result_it.contents.front();
451 if( alt_result.typeId() == comest_it.typeId() ) {
452 result_it = alt_result;
453 }
454 }
455 if( result_it.typeId() != comest_it.typeId() ) {
456 debugmsg( "When creating recipe result expected %s, got %s\n",
457 comest_it.typeId().str(), result_it.typeId().str() );
458 }
459 std::tie( this_min, this_max ) = compute_nutrient_range( result_it, rec, extra_flags );
460 min_nutr.min_in_place( this_min );
461 max_nutr.max_in_place( this_max );
462 }
463
464 return { min_nutr, max_nutr };
465}
size_t num_item_stacks() const
returns the number of items stacks in contents each item that is not count_by_charges,...
bool is_item_on_loop(const itype_id &) const
item create_result() const
Definition: recipe.cpp:459
recipe_dictionary recipe_dict
cata::value_ptr< islot_comestible > comestible
Definition: itype.h:821
std::vector< recipe_id > recipes
What recipes can make this item.
Definition: itype.h:985
bool has_flag(const std::string &flag) const
Definition: itype.cpp:146
const itype_id & get_id() const
Definition: itype.cpp:88

References itype::comestible, compute_default_effective_nutrients(), compute_nutrient_range(), item::contents, recipe::create_result(), debugmsg, flag_NUTRIENT_OVERRIDE(), item_contents::front(), itype::get_id(), itype::has_flag(), recipe_dictionary::is_item_on_loop(), nutrients::max_in_place(), nutrients::min_in_place(), item_contents::num_item_stacks(), recipe_dict, itype::recipes, string_id< T >::str(), calendar::turn, and item::typeId().

◆ conduct_blood_analysis()

void Character::conduct_blood_analysis ( ) const

Definition at line 1962 of file character.cpp.

1963{
1964 std::vector<std::string> effect_descriptions;
1965 std::vector<nc_color> colors;
1966
1967 for( auto &elem : *effects ) {
1968 if( elem.first->get_blood_analysis_description().empty() ) {
1969 continue;
1970 }
1971 effect_descriptions.emplace_back( elem.first->get_blood_analysis_description() );
1972 colors.emplace_back( elem.first->get_rating() == e_good ? c_green : c_red );
1973 }
1974
1975 const int win_w = 46;
1976 size_t win_h = 0;
1978 ui_adaptor ui;
1979 ui.on_screen_resize( [&]( ui_adaptor & ui ) {
1980 win_h = std::min( static_cast<size_t>( TERMY ),
1981 std::max<size_t>( 1, effect_descriptions.size() ) + 2 );
1982 w = catacurses::newwin( win_h, win_w,
1983 point( ( TERMX - win_w ) / 2, ( TERMY - win_h ) / 2 ) );
1984 ui.position_from_window( w );
1985 } );
1986 ui.mark_resize();
1987 ui.on_redraw( [&]( const ui_adaptor & ) {
1988 draw_border( w, c_red, string_format( " %s ", _( "Blood Test Results" ) ) );
1989 if( effect_descriptions.empty() ) {
1990 trim_and_print( w, point( 2, 1 ), win_w - 3, c_white, _( "No effects." ) );
1991 } else {
1992 for( size_t line = 1; line < ( win_h - 1 ) && line <= effect_descriptions.size(); ++line ) {
1993 trim_and_print( w, point( 2, line ), win_w - 3, colors[line - 1], effect_descriptions[line - 1] );
1994 }
1995 }
1996 wnoutrefresh( w );
1997 } );
1998 input_context ctxt( "BLOOD_TEST_RESULTS" );
1999 ctxt.register_action( "CONFIRM" );
2000 ctxt.register_action( "QUIT" );
2001 ctxt.register_action( "HELP_KEYBINDINGS" );
2002 bool stop = false;
2003 // Display new messages
2004 g->invalidate_main_ui_adaptor();
2005 while( !stop ) {
2007 const std::string action = ctxt.handle_input();
2008 if( action == "CONFIRM" || action == "QUIT" ) {
2009 stop = true;
2010 }
2011 }
2012}
A wrapper over a pointer to a curses window.
Definition: cursesdef.h:55
Represents a context in which a set of actions can be performed.
Definition: input.h:382
Adaptor between UI code and the UI management system.
Definition: ui_manager.h:65
@ action
Definition: dialogue.h:36
@ e_good
Definition: effect.h:30
void line(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6290
std::string colors()
Definition: path_info.cpp:146
window newwin(int nlines, int ncols, point begin)
Definition: ncurses_def.cpp:35
void wnoutrefresh(const window &win)
Definition: ncurses_def.cpp:44
void redraw()
Invalidate the top window and redraw all invalidated windows.
Definition: ui_manager.cpp:389
Definition: overmap_ui.h:17
int TERMX
Definition: output.cpp:47
int TERMY
Definition: output.cpp:48
void trim_and_print(const catacurses::window &w, point begin, const int width, const nc_color &base_color, const std::string &text, const report_color_error color_error)
Prints a single line of text.
Definition: output.cpp:214
void draw_border(const catacurses::window &w, nc_color border_color, const std::string &title, nc_color title_color)
Definition: output.cpp:575

References _, action, c_green, c_red, c_white, PATH_INFO::colors(), draw_border(), e_good, Creature::effects, g, input_context::handle_input(), line(), catacurses::newwin(), ui_manager::redraw(), input_context::register_action(), string_format(), TERMX, TERMY, trim_and_print(), and catacurses::wnoutrefresh().

Referenced by activate_bionic(), and iexamine::autodoc().

◆ consume()

void Character::consume ( item_location  loc)

Consume item (food, fuel, medicine, ...) at given location loc .

Definition at line 1548 of file consumption.cpp.

1549{
1550 item &target = *loc;
1551 const bool wielding = is_wielding( target );
1552 const bool worn = is_worn( target );
1553 const bool inv_item = !( wielding || worn );
1554
1555 if( consume_item( target ) ) {
1556
1557 const bool was_in_container = !can_consume_as_is( target );
1558
1559 if( was_in_container ) {
1560 i_rem( &target.contents.front() );
1561 } else {
1562 i_rem( &target );
1563 }
1564
1565 // Restack and sort so that we don't lie about target's invlet
1566 if( inv_item ) {
1567 inv.restack( *this->as_player() );
1568 }
1569
1570 if( was_in_container && wielding ) {
1571 add_msg_if_player( _( "You are now wielding an empty %s." ), primary_weapon().tname() );
1572 } else if( was_in_container && worn ) {
1573 add_msg_if_player( _( "You are now wearing an empty %s." ), target.tname() );
1574 } else if( was_in_container && !is_npc() ) {
1575 bool drop_it = false;
1576 if( get_option<std::string>( "DROP_EMPTY" ) == "no" ) {
1577 drop_it = false;
1578 } else if( get_option<std::string>( "DROP_EMPTY" ) == "watertight" ) {
1579 drop_it = !target.is_watertight_container();
1580 } else if( get_option<std::string>( "DROP_EMPTY" ) == "all" ) {
1581 drop_it = true;
1582 }
1583 if( drop_it ) {
1584 add_msg( _( "You drop the empty %s." ), target.tname() );
1586 } else {
1587 int quantity = inv.const_stack( inv.position_by_item( &target ) ).size();
1588 char letter = target.invlet ? target.invlet : ' ';
1589 add_msg( m_info, _( "%c - %d empty %s" ), letter, quantity, target.tname( quantity ) );
1590 }
1591 }
1592 } else if( inv_item ) {
1593 if( pickup::handle_spillable_contents( *this, target, g->m ) ) {
1594 i_rem( &target );
1595 }
1596 inv.restack( *this->as_player() );
1597 inv.unsort();
1598 }
1599}
bool consume_item(item &target)
Consume given item (food, fuel, medicine, ...).
bool is_wielding(const item &target) const
Definition: character.cpp:3230
void restack(player &p)
Definition: inventory.cpp:400
void unsort()
Definition: inventory.cpp:228
item remove_item(const item *it)
Remove a specific item from the inventory.
Definition: inventory.cpp:719
const std::list< item > & const_stack(int i) const
Definition: inventory.cpp:153
int position_by_item(const item *it) const
Returns the item position of the stack that contains the given item (compared by pointers).
Definition: inventory.cpp:830
bool is_watertight_container() const
Whether this is a container which can be used to store liquids.
Definition: item.cpp:6734
bool handle_spillable_contents(Character &c, item &it, map &m)
If character is handling a potentially spillable bucket, gracefully handle what to do with the conten...
Definition: pickup.cpp:1247

References _, add_msg(), Creature::add_msg_if_player(), Creature::as_player(), can_consume_as_is(), inventory::const_stack(), consume_item(), item::contents, deliberate, item_contents::front(), g, pickup::handle_spillable_contents(), i_rem(), inv, item::invlet, Creature::is_npc(), item::is_watertight_container(), is_wielding(), is_worn(), m_info, inventory::position_by_item(), primary_weapon(), put_into_vehicle_or_drop(), inventory::remove_item(), inventory::restack(), item::tname(), inventory::unsort(), and worn.

Referenced by npc::consume_cbm_items(), npc::consume_food(), avatar_action::eat(), avatar_funcs::use_item(), and npc::use_painkiller().

◆ consume_charges()

bool Character::consume_charges ( item used,
int  qty 
)

Consume charges of a tool or comestible item, potentially destroying it in the process.

Parameters
useditem consuming the charges
qtynumber of charges to consume which must be non-zero
Returns
true if item was destroyed

Definition at line 7420 of file character.cpp.

7421{
7422 if( qty < 0 ) {
7423 debugmsg( "Tried to consume negative charges" );
7424 return false;
7425 }
7426
7427 if( qty == 0 ) {
7428 return false;
7429 }
7430
7431 if( !used.is_tool() && !used.is_food() && !used.is_medication() ) {
7432 debugmsg( "Tried to consume charges for non-tool, non-food, non-med item" );
7433 return false;
7434 }
7435
7436 // Consume comestibles destroying them if no charges remain
7437 if( used.is_food() || used.is_medication() ) {
7438 used.charges -= qty;
7439 if( used.charges <= 0 ) {
7440 i_rem( &used );
7441 return true;
7442 }
7443 return false;
7444 }
7445
7446 // Tools which don't require ammo are instead destroyed
7447 if( used.is_tool() && !used.ammo_required() ) {
7448 i_rem( &used );
7449 return true;
7450 }
7451
7452 if( used.is_power_armor() ) {
7453 if( used.charges >= qty ) {
7454 used.ammo_consume( qty, pos() );
7455 } else if( character_funcs::can_interface_armor( *this ) && has_charges( itype_bio_armor, qty ) ) {
7457 } else {
7458 use_charges( itype_UPS, qty );
7459 }
7460 }
7461
7462 // USE_UPS never occurs on base items but is instead added by the UPS tool mod
7463 if( used.has_flag( flag_USE_UPS ) ) {
7464 // With the new UPS system, we'll want to use any charges built up in the tool before pulling from the UPS
7465 // The usage of the item was already approved, so drain item if possible, otherwise use UPS
7466 if( used.charges >= qty ) {
7467 used.ammo_consume( qty, pos() );
7468 } else {
7469 use_charges( itype_UPS, qty );
7470 }
7471 } else {
7472 used.ammo_consume( std::min( qty, used.ammo_remaining() ), pos() );
7473 }
7474 return false;
7475}
static const itype_id itype_UPS("UPS")
static const std::string flag_USE_UPS("USE_UPS")
static const itype_id itype_bio_armor("bio_armor")
std::list< item > use_charges(const itype_id &what, int qty, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: character.cpp:9668
int ammo_remaining() const
Quantity of ammunition currently loaded in tool, gun or auxiliary gunmod.
Definition: item.cpp:7384
bool is_tool() const
Definition: item.cpp:6968
int ammo_required() const
Quantity of ammunition consumed per usage of tool or with each shot of gun.
Definition: item.cpp:7454
bool is_food() const
Definition: item.cpp:6602
int ammo_consume(int qty, const tripoint &pos)
Consume ammo (if available) and return the amount of ammo that was consumed.
Definition: item.cpp:7482
bool can_interface_armor(const Character &who)
Check whether character has an active bionic capable of interfacing with power armor.

References item::ammo_consume(), item::ammo_remaining(), item::ammo_required(), character_funcs::can_interface_armor(), item::charges, debugmsg, flag_USE_UPS(), has_charges(), item::has_flag(), i_rem(), item::is_food(), item::is_medication(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, pos(), and use_charges().

Referenced by chop_plank_activity(), chop_tree_activity(), feedpet(), activity_handlers::firstaid_finish(), npc::heal_player(), npc::heal_self(), invoke_item(), activity_handlers::jackhammer_finish(), petfood(), activity_handlers::pickaxe_finish(), npc::pretend_heal(), activity_handlers::repair_item_finish(), activity_handlers::shear_finish(), activity_handlers::spellcasting_finish(), and activity_handlers::start_fire_finish().

◆ consume_effects()

bool Character::consume_effects ( item food)

Handles the effects of consuming an item.

Definition at line 1179 of file consumption.cpp.

1180{
1181 if( !food.is_comestible() ) {
1182 debugmsg( "called Character::consume_effects with non-comestible" );
1183 return false;
1184 }
1185
1186 if( has_trait( trait_THRESH_PLANT ) && food.type->can_use( "PLANTBLECH" ) ) {
1187 // Was used to cap nutrition and thirst, but no longer does this
1188 return false;
1189 }
1192 // No good can come of this.
1193 return false;
1194 }
1195
1196 const auto &comest = *food.get_comestible();
1197
1198 // Rotten food causes health loss
1199 const float relative_rot = food.get_relative_rot();
1200 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) &&
1202 const float rottedness = clamp( 2 * relative_rot - 2.0f, 0.1f, 1.0f );
1203 // ~-1 health per 1 nutrition at halfway-rotten-away, ~0 at "just got rotten"
1204 // But always round down
1205 int h_loss = -rottedness * comest.get_default_nutr();
1206 mod_healthy_mod( h_loss, -200 );
1207 add_msg( m_debug, "%d health from %0.2f%% rotten food", h_loss, rottedness );
1208 }
1209
1210 // Used in hibernation messages.
1211 const auto nutr = nutrition_for( food );
1212 const bool skip_health = has_trait( trait_PROJUNK2 ) && comest.healthy < 0;
1213 // We can handle junk just fine
1214 if( !skip_health ) {
1215 modify_health( comest );
1216 }
1217 modify_stimulation( comest );
1218 modify_fatigue( comest );
1219 modify_radiation( comest );
1220 modify_addiction( comest );
1221 modify_morale( food, nutr );
1222
1223 // Moved here and changed a bit - it was too complex
1224 // Incredibly minor stuff like this shouldn't require complexity
1225 if( !is_npc() && has_trait( trait_SLIMESPAWNER ) &&
1228 _( "You feel as though you're going to split open! In a good way?" ) );
1229 mod_pain( 5 );
1230 int numslime = 1;
1231 for( int i = 0; i < numslime; i++ ) {
1232 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
1233 slime->friendly = -1;
1234 }
1235 }
1236 mod_stored_kcal( -400 );
1237 mod_thirst( 40 );
1238 //~ slimespawns have *small voices* which may be the Nice equivalent
1239 //~ of the Rat King's ALL CAPS invective. Probably shared-brain telepathy.
1240 add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
1241 }
1242
1243 // Set up food for ingestion
1244 const item &contained_food = food.is_container() ? food.get_contained() : food;
1245 food_summary ingested{
1246 compute_effective_nutrients( contained_food )
1247 };
1248 // Maybe move tapeworm to digestion
1249 if( has_effect( effect_tapeworm ) ) {
1250 ingested.nutr /= 2;
1251 }
1252
1253 int excess_kcal = get_stored_kcal() + stomach.get_calories() + ingested.nutr.kcal -
1255
1256 // Moved hypermetabolism check here to prevent it being gimped by various bloating/vomit problems.
1257 if( excess_kcal > 0 && has_trait( trait_EATHEALTH ) ) {
1258 healall( roll_remainder( excess_kcal / 50.0f ) );
1259 mod_stored_kcal( -excess_kcal );
1260 excess_kcal = 0;
1261 }
1262
1263 int excess_quench = -( get_thirst() - comest.quench );
1264 stomach.ingest( ingested );
1265 mod_thirst( -contained_food.type->comestible->quench );
1266
1267
1268 if( ( excess_kcal > 0 || excess_quench > 0 ) && !food.has_flag( flag_NO_BLOAT ) &&
1270 add_effect( effect_bloated, 5_minutes );
1271 }
1272
1273 return true;
1274}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:149
void modify_addiction(const islot_comestible &comest)
Used to apply addiction modifications from food and medication.
void modify_stimulation(const islot_comestible &comest)
Used to apply stimulation modifications from food and medication.
void modify_morale(item &food, int nutr=0)
Used to apply morale modifications from food and medication.
void modify_radiation(const islot_comestible &comest)
Used to apply radiation from food and medication.
virtual void mod_thirst(int nthirst)
Definition: character.cpp:4439
stomach_contents stomach
Definition: character.h:1588
void modify_health(const islot_comestible &comest)
Used to apply health modifications from food and medication.
int nutrition_for(const item &comest) const
Handles the nutrition value for a comestible.
void healall(int dam)
Heals all body parts for dam.
Definition: character.cpp:8660
void modify_fatigue(const islot_comestible &comest)
Used to apply fatigue modifications from food and medication.
bool is_container() const
Whether this is container.
Definition: item.cpp:6729
double get_relative_rot() const
Get rot value relative to shelf life (or 0 if item does not spoil)
Definition: item.cpp:5558
const item & get_contained() const
Return a contained item (if any and only one).
Definition: item.cpp:7061
void ingest(const food_summary &ingested)
Directly adds food to stomach contents.
Definition: stomach.cpp:126
int get_calories() const
Definition: stomach.cpp:179
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const trait_id trait_THRESH_PLANT("THRESH_PLANT")
static const bionic_id bio_digestion("bio_digestion")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PROJUNK2("PROJUNK2")
static const trait_id trait_SAPROVORE("SAPROVORE")
static const efftype_id effect_bloated("bloated")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_GOURMAND("GOURMAND")
static const trait_id trait_SAPROPHAGE("SAPROPHAGE")
static const std::string flag_NO_BLOAT("NO_BLOAT")
bool can_use(const std::string &iuse_name) const
Definition: itype.cpp:161

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), bio_digestion, itype::can_use(), clamp(), itype::comestible, compute_effective_nutrients(), debugmsg, effect_bloated, effect_tapeworm, flag_NO_BLOAT(), g, stomach_contents::get_calories(), item::get_comestible(), item::get_contained(), item::get_relative_rot(), get_stored_kcal(), get_thirst(), item::has_any_flag(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), healall(), herbivore_blacklist(), stomach_contents::ingest(), item::is_comestible(), item::is_container(), Creature::is_npc(), m_debug, m_good, m_mixed, max_stored_kcal(), mod_healthy_mod(), mod_pain(), mod_stored_kcal(), mod_thirst(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), mon_player_blob, nutrition_for(), pos(), roll_remainder(), slaked, stomach, trait_EATHEALTH, trait_GOURMAND, trait_HERBIVORE, trait_PROJUNK2, trait_RUMINANT, trait_SAPROPHAGE, trait_SAPROVORE, trait_SLIMESPAWNER, trait_THRESH_PLANT, and item::type.

Referenced by consume_med(), eat(), iuse::ecig(), and try_consume().

◆ consume_item()

bool Character::consume_item ( item target)

Consume given item (food, fuel, medicine, ...).

Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1510 of file consumption.cpp.

1511{
1512 if( target.is_null() ) {
1513 add_msg_if_player( m_info, _( "You do not have that item." ) );
1514 return false;
1515 }
1517 add_msg_if_player( m_info, _( "You can't do that while underwater." ) );
1518 return false;
1519 }
1520
1521 item &comest = get_consumable_from( target );
1522
1523 if( comest.is_null() || target.is_craft() ) {
1524 add_msg_if_player( m_info, _( "You can't eat your %s." ), target.tname() );
1525 if( is_npc() ) {
1526 debugmsg( "%s tried to eat a %s", name, target.tname() );
1527 }
1528 return false;
1529 }
1530 if( is_avatar() && !query_consume_ownership( target, *as_avatar() ) ) {
1531 return false;
1532 }
1533 if( consume_med( comest ) ||
1534 eat( comest ) ||
1535 feed_furnace_with( comest ) ||
1536 fuel_bionic_with( comest ) ) {
1537
1538 if( target.is_container() ) {
1539 target.on_contents_changed();
1540 }
1541
1542 return comest.charges <= 0;
1543 }
1544
1545 return false;
1546}
bool eat(item &food, bool force=false)
Used for eating entered comestible, returns true if comestible is successfully eaten.
bool feed_furnace_with(item &it)
Recharge CBMs whenever possible.
bool fuel_bionic_with(item &it)
item & get_consumable_from(item &it) const
Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consu...
bool consume_med(item &target)
Consume an item as medication.
virtual bool is_avatar() const
Definition: creature.h:95
void on_contents_changed()
Callback when contents of the item are affected in any way other than just processing.
Definition: item.cpp:4560
bool query_consume_ownership(item &target, avatar &you)

References _, Creature::add_msg_if_player(), Creature::as_avatar(), item::charges, consume_med(), debugmsg, eat(), feed_furnace_with(), fuel_bionic_with(), get_consumable_from(), has_trait(), Creature::is_avatar(), item::is_container(), item::is_craft(), Creature::is_npc(), item::is_null(), Creature::is_underwater(), m_info, name, item::on_contents_changed(), query_consume_ownership(), item::tname(), and trait_WATERSLEEP.

Referenced by consume(), and avatar_action::eat().

◆ consume_med()

bool Character::consume_med ( item target)

Consume an item as medication.

Parameters
targetItem consumed. Must be a medication or a container of medication.
Returns
true if item should be destroyed (last charge was consumed)

Definition at line 1602 of file consumption.cpp.

1603{
1604 if( !target.is_medication() ) {
1605 return false;
1606 }
1607
1608 const itype_id tool_type = target.get_comestible()->tool;
1609 const itype *req_tool = &*tool_type;
1610 bool check_tool = true;
1611 if( tool_type == itype_syringe && has_bionic( bio_syringe ) ) {
1612 check_tool = false;
1613 }
1614 if( req_tool->tool ) {
1615 if( check_tool && !(
1616 has_amount( tool_type, 1 ) &&
1617 has_charges( tool_type, req_tool->tool->charges_per_use )
1618 ) ) {
1619 add_msg_if_player( m_info, _( "You need a %s to consume that!" ), req_tool->nname( 1 ) );
1620 return false;
1621 }
1622 use_charges( tool_type, req_tool->tool->charges_per_use );
1623 }
1624
1625 int amount_used = 1;
1626 if( target.type->has_use() ) {
1627 amount_used = target.type->invoke( *this->as_player(), target, pos() );
1628 if( amount_used <= 0 ) {
1629 return false;
1630 }
1631 }
1632
1633 // TODO: Get the target it was used on
1634 // Otherwise injecting someone will give us addictions etc.
1635 if( target.has_flag( "NO_INGEST" ) ) {
1636 const auto &comest = *target.get_comestible();
1637 // Assume that parenteral meds don't spoil, so don't apply rot
1638 modify_health( comest );
1639 modify_stimulation( comest );
1640 modify_fatigue( comest );
1641 modify_radiation( comest );
1642 modify_addiction( comest );
1643 modify_morale( target );
1644 } else {
1645 // Take by mouth
1646 consume_effects( target );
1647 }
1648
1649 mod_moves( -250 );
1650 target.charges -= amount_used;
1651 return target.charges <= 0;
1652}
bool consume_effects(item &food)
Handles the effects of consuming an item.
static const bionic_id bio_syringe("bio_syringe")
static const itype_id itype_syringe("syringe")
cata::value_ptr< islot_tool > tool
Definition: itype.h:820
bool has_use() const
Definition: itype.cpp:141
int invoke(player &p, item &it, const tripoint &pos) const
Definition: itype.cpp:180
std::string nname(unsigned int quantity) const
Definition: itype.cpp:78

References _, Creature::add_msg_if_player(), Creature::as_player(), bio_syringe, item::charges, consume_effects(), item::get_comestible(), visitable< Character >::has_amount(), has_bionic(), has_charges(), item::has_flag(), itype::has_use(), itype::invoke(), item::is_medication(), itype_syringe, m_info, Creature::mod_moves(), modify_addiction(), modify_fatigue(), modify_health(), modify_morale(), modify_radiation(), modify_stimulation(), itype::nname(), pos(), itype::tool, item::type, and use_charges().

Referenced by consume_item().

◆ consume_remote_fuel()

int Character::consume_remote_fuel ( int  amount)

Consume fuel used by remote powered bionic, return amount of request unfulfilled (0 if totally successful).

Definition at line 1453 of file bionics.cpp.

1454{
1455 int unconsumed_amount = amount;
1456 const std::vector<item *> cables = items_with( []( const item & it ) {
1457 return it.active && it.has_flag( flag_CABLE_SPOOL );
1458 } );
1459
1460 map &here = get_map();
1461 for( const item *cable : cables ) {
1462 const std::optional<tripoint> target = cable->get_cable_target( this, pos() );
1463 if( target ) {
1464 const optional_vpart_position vp = here.veh_at( *target );
1465 if( !vp ) {
1466 continue;
1467 }
1468 unconsumed_amount = vp->vehicle().discharge_battery( amount );
1469 }
1470 }
1471
1472 if( unconsumed_amount > 0 ) {
1473 static const item_filter used_ups = [&]( const item & itm ) {
1474 return itm.get_var( "cable" ) == "plugged_in";
1475 };
1476 if( has_charges( itype_UPS_off, unconsumed_amount, used_ups ) ) {
1477 use_charges( itype_UPS_off, unconsumed_amount, used_ups );
1478 unconsumed_amount -= 1;
1479 } else if( has_charges( itype_adv_UPS_off, unconsumed_amount, used_ups ) ) {
1480 use_charges( itype_adv_UPS_off, roll_remainder( unconsumed_amount * 0.6 ), used_ups );
1481 unconsumed_amount -= 1;
1482 }
1483 }
1484
1485 return unconsumed_amount;
1486}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS_off("UPS_off")
std::function< bool(const item &)> item_filter
Definition: game.h:119

References item::active, flag_CABLE_SPOOL(), get_map(), has_charges(), item::has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, pos(), roll_remainder(), and use_charges().

Referenced by burn_fuel().

◆ cough()

void Character::cough ( bool  harmful = false,
int  loudness = 4 
)

Definition at line 7553 of file character.cpp.

7554{
7556 return;
7557 }
7558
7559 if( harmful ) {
7560 const int stam = get_stamina();
7561 const int malus = get_stamina_max() * 0.05; // 5% max stamina
7562 mod_stamina( -malus );
7563 if( stam < malus && x_in_y( malus - stam, malus ) && one_in( 6 ) ) {
7564 apply_damage( nullptr, bodypart_id( "torso" ), 1 );
7565 }
7566 // Asthmatic characters gain increased risk of an asthma attack from smoke and other dangerous respiratory effects.
7567 if( has_trait( trait_ASTHMA ) ) {
7569 }
7570 }
7571
7572 if( !is_npc() ) {
7573 add_msg( m_bad, _( "You cough heavily." ) );
7574 }
7575 sounds::sound( pos(), loudness, sounds::sound_t::speech, _( "a hacking cough." ), false, "misc",
7576 "cough" );
7577
7578 moves -= 80;
7579
7580 add_effect( effect_recently_coughed, 5_minutes );
7581}
static const efftype_id effect_cough_suppress("cough_suppress")
static const efftype_id effect_recently_coughed("recently_coughed")
static const efftype_id effect_cough_aggravated_asthma("cough_aggravated_asthma")
static const trait_id trait_ASTHMA("ASTHMA")

References _, Creature::add_effect(), add_msg(), apply_damage(), effect_cough_aggravated_asthma, effect_cough_suppress, effect_recently_coughed, get_stamina(), get_stamina_max(), Creature::has_effect(), has_trait(), Creature::is_npc(), m_bad, mod_stamina(), Creature::moves, one_in(), pos(), sounds::sound(), sounds::speech, trait_ASTHMA, and x_in_y().

Referenced by eff_fun_fungus(), and process_one_effect().

◆ covered_with_flag()

bool Character::covered_with_flag ( const std::string &  flag,
const body_part_set parts 
) const

Definition at line 8979 of file character.cpp.

8980{
8981 if( parts.none() ) {
8982 return true;
8983 }
8984
8985 body_part_set to_cover( parts );
8986
8987 for( const auto &elem : worn ) {
8988 if( !elem.has_flag( flag ) ) {
8989 continue;
8990 }
8991
8992 to_cover &= ~elem.get_covered_body_parts();
8993
8994 if( to_cover.none() ) {
8995 return true; // Allows early exit.
8996 }
8997 }
8998
8999 return to_cover.none();
9000}
bool none() const
Definition: bodypart.h:268

References body_part_set::none(), and worn.

Referenced by is_waterproof().

◆ crafting_inventory() [1/2]

const inventory & Character::crafting_inventory ( bool  clear_path)

Definition at line 557 of file crafting.cpp.

558{
559 return crafting_inventory( tripoint_zero, PICKUP_RANGE, clear_path );
560}
const inventory & crafting_inventory(bool clear_path)
Definition: crafting.cpp:557

References crafting_inventory(), PICKUP_RANGE, and tripoint_zero.

Referenced by iexamine::autodoc(), autodoc_internal(), game::butcher(), activity_handlers::butcher_finish(), butcher_submenu(), can_butcher_at(), player::can_continue_craft(), can_do_activity_there(), player::can_make(), player::can_start_craft(), complete_craft(), veh_interact::complete_vehicle(), consider_butchery(), construction_color(), activity_handlers::cracking_do_turn(), iuse::craft(), crafting_inventory(), iexamine::cvdmachine(), iuse::dig(), game_menus::inv::disassemble(), item::final_info(), wash_activity_actor::finish(), bionic_install_preset::get_failure_chance(), repair_item_actor::handle_components(), has_enough_anesth(), list_available_constructions(), avatar_funcs::mend_item(), activity_handlers::mend_item_finish(), mill_load_food(), iuse::modify_grid_connections(), modify_morale(), veh_utils::most_repairable_part(), iexamine::nanofab(), iexamine::pit(), prompt_disassemble_in_seq(), examine_item_menu::rate_action_disassemble(), veh_utils::repair_part(), iexamine::safe(), deduped_requirement_data::select_alternative(), select_crafting_recipe(), iexamine::sign(), smoker_load_food(), iexamine::tree_maple(), disassemble_activity_actor::try_start_single(), sew_advanced_actor::use(), and wash_items().

◆ crafting_inventory() [2/2]

const inventory & Character::crafting_inventory ( const tripoint src_pos = tripoint_zero,
int  radius = PICKUP_RANGE,
bool  clear_path = true 
)

Definition at line 562 of file crafting.cpp.

564{
565 tripoint inv_pos = src_pos;
566 if( src_pos == tripoint_zero ) {
567 inv_pos = pos();
568 }
569 if( cached_moves == moves
571 && cached_position == inv_pos ) {
573 }
574 cached_crafting_inventory.form_from_map( inv_pos, radius, this, false, clear_path );
578 for( const bionic &bio : *my_bionics ) {
579 const bionic_data &bio_data = bio.info();
580 if( ( !bio_data.activated || bio.powered ) &&
581 !bio_data.fake_item.is_empty() ) {
582 cached_crafting_inventory += item( bio.info().fake_item,
584 }
585 }
586 if( has_trait( trait_BURROW ) ) {
589 }
590
593 cached_position = inv_pos;
594 // cache the qualities of the items in cached_crafting_inventory
597}
tripoint cached_position
Definition: character.h:2272
int cached_moves
Definition: character.h:2271
inventory cached_crafting_inventory
Definition: character.h:2273
void form_from_map(const tripoint &origin, int range, const Character *pl=nullptr, bool assign_invlet=true, bool clear_path=true)
Definition: inventory.cpp:474
void update_quality_cache()
Definition: inventory.cpp:1118
static const trait_id trait_BURROW("BURROW")
bool activated
Is true if a bionic is an active instead of a passive bionic.
Definition: bionics.h:53

References bionic_data::activated, cached_crafting_inventory, cached_moves, cached_position, cached_time, bionic_data::fake_item, inventory::form_from_map(), get_power_level(), has_trait(), inv, string_id< T >::is_empty(), Creature::moves, my_bionics, pos(), primary_weapon(), units::to_kilojoule(), trait_BURROW, tripoint_zero, calendar::turn, inventory::update_quality_cache(), and worn.

◆ crit_chance()

double Character::crit_chance ( float  roll_hit,
float  target_dodge,
const item weap 
) const

Returns the chance to critical given a hit roll and target's dodge roll.

Unarmed increases critical chance with UNARMED_WEAPON Dexterity increases chance for critical hits Perception increases chance for critical hits Bashing increases critical chance with bashing weapons Cutting increases critical chance with cutting weapons Stabbing increases critical chance with piercing weapons Unarmed increases critical chance with unarmed weapons Melee slightly increases critical chance with any item

Definition at line 796 of file melee.cpp.

797{
798 // Weapon to-hit roll
799 double weapon_crit_chance = 0.5;
800 if( weap.is_unarmed_weapon() ) {
801 // Unarmed attack: 1/2 of unarmed skill is to-hit
802 /** @EFFECT_UNARMED increases critical chance with UNARMED_WEAPON */
803 weapon_crit_chance = 0.5 + 0.05 * get_skill_level( skill_unarmed );
804 }
805
806 if( weap.type->m_to_hit > 0 ) {
807 weapon_crit_chance = std::max( weapon_crit_chance, 0.5 + 0.1 * weap.type->m_to_hit );
808 } else if( weap.type->m_to_hit < 0 ) {
809 weapon_crit_chance += 0.1 * weap.type->m_to_hit;
810 }
811 weapon_crit_chance = limit_probability( weapon_crit_chance );
812
813 // Dexterity and perception
814 /** @EFFECT_DEX increases chance for critical hits */
815
816 /** @EFFECT_PER increases chance for critical hits */
817 const double stat_crit_chance = limit_probability( 0.25 + 0.01 * dex_cur + ( 0.02 * per_cur ) );
818
819 /** @EFFECT_BASHING increases critical chance with bashing weapons */
820 /** @EFFECT_CUTTING increases critical chance with cutting weapons */
821 /** @EFFECT_STABBING increases critical chance with piercing weapons */
822 /** @EFFECT_UNARMED increases critical chance with unarmed weapons */
823 int sk = get_skill_level( weap.melee_skill() );
824 if( has_active_bionic( bio_cqb ) ) {
825 sk = std::max( sk, BIO_CQB_LEVEL );
826 }
827
828 /** @EFFECT_MELEE slightly increases critical chance with any item */
829 sk += get_skill_level( skill_melee ) / 2.5;
830
831 const double skill_crit_chance = limit_probability( 0.25 + sk * 0.025 );
832
833 // Examples (survivor stats/chances of each critical):
834 // Fresh (skill-less) 8/8/8/8, unarmed:
835 // 50%, 49%, 25%; ~1/16 guaranteed critical + ~1/8 if roll>dodge*1.5
836 // Expert (skills 10) 10/10/10/10, unarmed:
837 // 100%, 55%, 60%; ~1/3 guaranteed critical + ~4/10 if roll>dodge*1.5
838 // Godlike with combat CBM 20/20/20/20, pipe (+1 accuracy):
839 // 60%, 100%, 42%; ~1/4 guaranteed critical + ~3/8 if roll>dodge*1.5
840
841 // Note: the formulas below are only valid if none of the 3 critical chance values go above 1.0
842 // It is therefore important to limit them to between 0.0 and 1.0
843
844 // Chance to get all 3 criticals (a guaranteed critical regardless of hit/dodge)
845 const double chance_triple = weapon_crit_chance * stat_crit_chance * skill_crit_chance;
846 // Only check double critical (one that requires hit/dodge comparison) if we have good
847 // hit vs dodge
848 if( roll_hit > target_dodge * 3 / 2 ) {
849 const double chance_double = 0.5 * (
850 weapon_crit_chance * stat_crit_chance +
851 stat_crit_chance * skill_crit_chance +
852 weapon_crit_chance * skill_crit_chance -
853 ( 3 * chance_triple ) );
854 // Because chance_double already removed the triples with -( 3 * chance_triple ),
855 // chance_triple and chance_double are mutually exclusive probabilities and can just
856 // be added together.
858 melee::melee_stats.double_crit_chance += chance_double + chance_triple;
859 return chance_triple + chance_double;
860 }
862 melee::melee_stats.crit_chance += chance_triple;
863 return chance_triple;
864}
bool is_unarmed_weapon() const
Definition: item.cpp:743
skill_id melee_skill() const
The most relevant skill used with this melee weapon.
Definition: item.cpp:7205
double limit_probability(double unbounded_probability)
Limits a probability to be between 0.0 and 1.0.
Definition: melee.cpp:791
melee_statistic_data melee_stats
Definition: melee.cpp:2520
int m_to_hit
Definition: itype.h:969
double crit_chance
Definition: melee.h:15
int double_crit_count
Definition: melee.h:11
double double_crit_chance
Definition: melee.h:14

References bio_cqb, BIO_CQB_LEVEL, melee_statistic_data::crit_chance, melee_statistic_data::crit_count, dex_cur, melee_statistic_data::double_crit_chance, melee_statistic_data::double_crit_count, get_skill_level(), has_active_bionic(), item::is_unarmed_weapon(), limit_probability(), itype::m_to_hit, item::melee_skill(), melee::melee_stats, per_cur, skill_melee, skill_unarmed, and item::type.

Referenced by item::combat_info(), item::effective_dps(), and scored_crit().

◆ crossed_threshold()

bool Character::crossed_threshold ( ) const

Returns true if the player has crossed a mutation threshold Player can only cross one mutation threshold.

Definition at line 8723 of file character.cpp.

8724{
8725 for( const trait_id &mut : get_mutations() ) {
8726 if( mut->threshold ) {
8727 return true;
8728 }
8729 }
8730 return false;
8731}

References get_mutations(), and mutation_branch::threshold.

Referenced by character_display::disp_info(), draw_tip(), hardcoded_effects(), marloss_common(), modify_morale(), conditional_t< T >::set_has_trait_flag(), and test_crossing_threshold().

◆ deactivate_bionic()

bool Character::deactivate_bionic ( bionic bio,
bool  eff_only = false 
)

Handles bionic deactivation effects of the entered bionic, returns if anything deactivated.

Definition at line 1107 of file bionics.cpp.

1108{
1109 if( bio.incapacitated_time > 0_turns ) {
1110 add_msg_if_player( m_info, _( "Your %s is shorting out and can't be deactivated." ),
1111 bio.info().name );
1112 return false;
1113 }
1114
1115 if( bio.info().is_remote_fueled ) {
1117 }
1118
1119 // Just do the effect, no stat changing or messages
1120 if( !eff_only ) {
1121 if( !bio.powered ) {
1122 // It's already off!
1123 return false;
1124 }
1125 if( !bio.info().has_flag( flag_BIONIC_TOGGLED ) ) {
1126 // It's a fire-and-forget bionic, we can't turn it off but have to wait for
1127 //it to run out of charge
1128 add_msg_if_player( m_info, _( "You can't deactivate your %s manually!" ),
1129 bio.info().name );
1130 return false;
1131 }
1132 if( get_power_level() < bio.info().power_deactivate ) {
1133 add_msg_if_player( m_info, _( "You don't have the power to deactivate your %s." ),
1134 bio.info().name );
1135 return false;
1136 }
1137
1138 //We can actually deactivate now, do deactivation-y things
1140 bio.powered = false;
1141 add_msg_if_player( m_neutral, _( "You deactivate your %s." ), bio.info().name );
1142 }
1143
1144 // Deactivation effects go here
1145 if( bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
1146 if( primary_weapon().typeId() == bio.info().fake_item ) {
1147 add_msg_if_player( _( "You withdraw your %s." ), primary_weapon().tname() );
1148 if( g->u.sees( pos() ) ) {
1149 add_msg_if_npc( m_info, _( "<npcname> withdraws their %s." ), primary_weapon().tname() );
1150 }
1151 bio.ammo_loaded =
1152 primary_weapon().ammo_data() != nullptr ? primary_weapon().ammo_data()->get_id() :
1154 bio.ammo_count = static_cast<unsigned int>( primary_weapon().ammo_remaining() );
1157 }
1158 } else if( bio.id == bio_cqb ) {
1159 martial_arts_data->selected_style_check();
1160 } else if( bio.id == bio_remote ) {
1161 if( g->remoteveh() != nullptr && !has_active_item( itype_remotevehcontrol ) ) {
1162 g->setremoteveh( nullptr );
1163 } else if( !get_value( "remote_controlling" ).empty() &&
1165 set_value( "remote_controlling", "" );
1166 }
1167 } else if( bio.id == bio_tools ) {
1169 } else if( bio.id == bio_ads ) {
1171 bio.energy_stored = 0_kJ;
1172 }
1173
1174 // Recalculate stats (strength, mods from pain etc.) that could have been affected
1176 reset();
1177 if( !bio.id->enchantments.empty() ) {
1179 }
1180
1181 // Also reset crafting inventory cache if this bionic spawned a fake item
1182 if( !bio.info().fake_item.is_empty() ) {
1184 }
1185
1186 // Compatibility with old saves without the toolset hammerspace
1187 if( !eff_only && bio.id == bio_tools && !has_bionic( bionic_TOOLS_EXTEND ) ) {
1188 // E X T E N D T O O L S
1190 }
1191
1192 return true;
1193}
static const bionic_id bio_ads("bio_ads")
static const itype_id itype_remotevehcontrol("remotevehcontrol")
static const bionic_id bionic_TOOLS_EXTEND("bio_tools_extend")
static const itype_id itype_radiocontrol("radiocontrol")
bool has_active_item(const itype_id &id) const
Whether the player carries an active item of the given item type.
Definition: character.cpp:2510
void reset_remote_fuel()
Definition: bionics.cpp:1488
virtual void add_msg_if_npc(const std::string &) const
Definition: creature.h:647
const itype * ammo_data() const
Specific ammo data, returns nullptr if item is neither ammo nor loaded with any.
Definition: item.cpp:7535
static const string_id< itype > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
units::energy power_deactivate
Power cost on deactivation.
Definition: bionics.h:39

References _, add_bionic(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), bionic::ammo_count, item::ammo_data(), bionic::ammo_loaded, item::ammo_remaining(), bio_ads, bio_cqb, bio_remote, bio_tools, bionic_TOOLS_EXTEND, bionic_data::enchantments, bionic::energy_stored, bionic_data::fake_item, flag_BIONIC_TOGGLED, flag_BIONIC_WEAPON, g, itype::get_id(), get_power_level(), Creature::get_value(), has_active_item(), has_bionic(), bionic_data::has_flag(), bionic::id, bionic::incapacitated_time, bionic::info(), invalidate_crafting_inventory(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, itype_radiocontrol, itype_remotevehcontrol, m_info, m_neutral, martial_arts_data, mod_power_level(), bionic_data::name, string_id< itype >::NULL_ID(), pos(), bionic_data::power_deactivate, bionic::powered, primary_weapon(), recalculate_enchantment_cache(), reset(), reset_encumbrance(), reset_remote_fuel(), set_primary_weapon(), and Creature::set_value().

Referenced by absorb_hit(), burn_fuel(), npc::deactivate_bionic_by_id(), deactivate_weapon_cbm(), process_bionic(), show_bionics_ui(), and uninstall_bionic().

◆ deactivate_mutation()

void Character::deactivate_mutation ( const trait_id mut)

Definition at line 595 of file mutation.cpp.

596{
597 my_mutations[mut].powered = false;
598
599 // Handle stat changes from deactivation
600 apply_mods( mut, false );
602 const mutation_branch &mdata = mut.obj();
603 if( mdata.transform ) {
604 const cata::value_ptr<mut_transform> trans = mdata.transform;
605 mod_moves( -trans->moves );
606 switch_mutations( mut, trans->target, trans->active );
607 }
608
609 if( !mut->enchantments.empty() ) {
611 }
612}
void apply_mods(const trait_id &mut, bool add_remove)
Applies stat mods to character.
Definition: mutation.cpp:204
std::vector< enchantment_id > enchantments
mutation enchantments
Definition: mutation.h:238

References apply_mods(), mutation_branch::enchantments, Creature::mod_moves(), my_mutations, string_id< T >::obj(), recalc_sight_limits(), recalculate_enchantment_cache(), switch_mutations(), and mutation_branch::transform.

Referenced by show_mutations_ui(), and detail::show_mutations_ui_internal().

◆ deal_damage()

dealt_damage_instance Character::deal_damage ( Creature source,
bodypart_id  bp,
const damage_instance d 
)
overridevirtual

Calls Creature::deal_damage and handles damaged effects (waking up, etc.)

Dexterity increases chance to avoid being grabbed

Reimplemented from Creature.

Definition at line 8466 of file character.cpp.

8468{
8469 if( has_trait( trait_DEBUG_NODMG ) ) {
8470 return dealt_damage_instance();
8471 }
8472
8473 const body_part bp_token = bp->token;
8474 if( bp_token == num_bp ) {
8475 debugmsg( "Wacky bodypart hit!" );
8476 return dealt_damage_instance();
8477 }
8478
8479 //damage applied here
8480 dealt_damage_instance dealt_dams = Creature::deal_damage( source, bp, d );
8481 //block reduction should be by applied this point
8482 int dam = dealt_dams.total_damage();
8483
8484 // TODO: Pre or post blit hit tile onto "this"'s location here
8485 if( dam > 0 && g->u.sees( pos() ) ) {
8486 g->draw_hit_player( *this, dam );
8487
8488 if( is_player() && source ) {
8489 //monster hits player melee
8490 SCT.add( point( posx(), posy() ),
8491 direction_from( point_zero, point( posx() - source->posx(), posy() - source->posy() ) ),
8492 get_hp_bar( dam, get_hp_max( bp ) ).first, m_bad, body_part_name( bp ), m_neutral );
8493 }
8494 }
8495
8496 // handle snake artifacts
8497 if( has_artifact_with( AEP_SNAKES ) && dam >= 6 ) {
8498 const int snakes = dam / 6;
8499 int spawned = 0;
8500 for( int i = 0; i < snakes; i++ ) {
8501 if( monster *const snake = g->place_critter_around( mon_shadow_snake, pos(), 1 ) ) {
8502 snake->friendly = -1;
8503 spawned++;
8504 }
8505 }
8506 if( spawned == 1 ) {
8507 add_msg( m_warning, _( "A snake sprouts from your body!" ) );
8508 } else if( spawned >= 2 ) {
8509 add_msg( m_warning, _( "Some snakes sprout from your body!" ) );
8510 }
8511 }
8512
8513 // And slimespawners too
8514 if( ( has_trait( trait_SLIMESPAWNER ) ) && ( dam >= 10 ) && one_in( 20 - dam ) ) {
8515 if( monster *const slime = g->place_critter_around( mon_player_blob, pos(), 1 ) ) {
8516 slime->friendly = -1;
8517 add_msg_if_player( m_warning, _( "Slime is torn from you, and moves on its own!" ) );
8518 }
8519 }
8520
8521 //Acid blood effects.
8522 bool u_see = g->u.sees( *this );
8523 int cut_dam = dealt_dams.type_damage( DT_CUT );
8524 if( source && has_trait( trait_ACIDBLOOD ) && !one_in( 3 ) &&
8525 ( dam >= 4 || cut_dam > 0 ) && ( rl_dist( g->u.pos(), source->pos() ) <= 1 ) ) {
8526 if( is_player() ) {
8527 add_msg( m_good, _( "Your acidic blood splashes %s in mid-attack!" ),
8528 source->disp_name() );
8529 } else if( u_see ) {
8530 add_msg( _( "%1$s's acidic blood splashes on %2$s in mid-attack!" ),
8531 disp_name(), source->disp_name() );
8532 }
8533 damage_instance acidblood_damage;
8534 acidblood_damage.add_damage( DT_ACID, rng( 4, 16 ) );
8535 if( !one_in( 4 ) ) {
8536 source->deal_damage( this, bodypart_id( "arm_l" ), acidblood_damage );
8537 source->deal_damage( this, bodypart_id( "arm_r" ), acidblood_damage );
8538 } else {
8539 source->deal_damage( this, bodypart_id( "torso" ), acidblood_damage );
8540 source->deal_damage( this, bodypart_id( "head" ), acidblood_damage );
8541 }
8542 }
8543
8544 int recoil_mul = 100;
8545
8546 if( bp == bodypart_id( "eyes" ) ) {
8547 if( dam > 5 || cut_dam > 0 ) {
8548 const time_duration minblind = std::max( 1_turns, 1_turns * ( dam + cut_dam ) / 10 );
8549 const time_duration maxblind = std::min( 5_turns, 1_turns * ( dam + cut_dam ) / 4 );
8550 add_effect( effect_blind, rng( minblind, maxblind ) );
8551 }
8552 } else if( bp == bodypart_id( "hand_l" ) || bp == bodypart_id( "arm_l" ) ||
8553 bp == bodypart_id( "hand_r" ) || bp == bodypart_id( "arm_r" ) ) {
8554 recoil_mul = 200;
8555 } else if( bp == bodypart_id( "num_bp" ) ) {
8556 debugmsg( "Wacky body part hit!" );
8557 }
8558
8559
8560
8561 // TODO: Scale with damage in a way that makes sense for power armors, plate armor and naked skin.
8562 const item &weapon = primary_weapon();
8563 recoil += recoil_mul * weapon.volume() / 250_ml;
8564 recoil = std::min( MAX_RECOIL, recoil );
8565 //looks like this should be based off of dealt damages, not d as d has no damage reduction applied.
8566 // Skip all this if the damage isn't from a creature. e.g. an explosion.
8567 if( source != nullptr ) {
8568 if( source->has_flag( MF_GRABS ) && !source->is_hallucination() &&
8569 !source->has_effect( effect_grabbing ) ) {
8570 /** @EFFECT_DEX increases chance to avoid being grabbed */
8571
8572 if( has_grab_break_tec() && ( rng( 0, get_dex() ) > rng( 0, 10 ) ) ) {
8573 if( has_effect( effect_grabbed ) ) {
8574 add_msg_if_player( m_warning, _( "The %s tries to grab you as well, but you bat it away!" ),
8575 source->disp_name() );
8576 } else {
8577 add_msg_player_or_npc( m_info, _( "The %s tries to grab you, but you break its grab!" ),
8578 _( "The %s tries to grab <npcname>, but they break its grab!" ),
8579 source->disp_name() );
8580 }
8581 } else {
8582 int prev_effect = get_effect_int( effect_grabbed );
8583 add_effect( effect_grabbed, 2_turns, bp_torso, prev_effect + 2 );
8584 source->add_effect( effect_grabbing, 2_turns );
8585 add_msg_player_or_npc( m_bad, _( "You are grabbed by %s!" ), _( "<npcname> is grabbed by %s!" ),
8586 source->disp_name() );
8587 }
8588 }
8589 }
8590
8591 if( get_option<bool>( "FILTHY_WOUNDS" ) ) {
8592 int sum_cover = 0;
8593 for( const item &i : worn ) {
8594 if( i.covers( bp->token ) && i.is_filthy() ) {
8595 sum_cover += i.get_coverage();
8596 }
8597 }
8598
8599 // Chance of infection is damage (with cut and stab x4) * sum of coverage on affected body part, in percent.
8600 // i.e. if the body part has a sum of 100 coverage from filthy clothing,
8601 // each point of damage has a 1% change of causing infection.
8602 if( sum_cover > 0 ) {
8603 const int cut_type_dam = dealt_dams.type_damage( DT_CUT ) + dealt_dams.type_damage( DT_STAB );
8604 const int combined_dam = dealt_dams.type_damage( DT_BASH ) + ( cut_type_dam * 4 );
8605 const int infection_chance = ( combined_dam * sum_cover ) / 100;
8606 if( x_in_y( infection_chance, 100 ) ) {
8607 if( has_effect( effect_bite, bp->token ) ) {
8608 add_effect( effect_bite, 40_minutes, bp->token );
8609 } else if( has_effect( effect_infected, bp->token ) ) {
8610 add_effect( effect_infected, 25_minutes, bp->token );
8611 } else {
8612 add_effect( effect_bite, 1_turns, bp->token );
8613 }
8614 add_msg_if_player( _( "Filth from your clothing has implanted deep in the wound." ) );
8615 }
8616 }
8617 }
8618
8619 on_hurt( source );
8620 return dealt_dams;
8621}
static const efftype_id effect_blind("blind")
static const trait_id trait_SLIMESPAWNER("SLIMESPAWNER")
static const mtype_id mon_player_blob("mon_player_blob")
static const efftype_id effect_grabbing("grabbing")
static const mtype_id mon_shadow_snake("mon_shadow_snake")
static const efftype_id effect_grabbed("grabbed")
double recoil
Definition: character.h:571
virtual int posy() const =0
virtual std::string disp_name(bool possessive=false, bool capitalize_first=false) const =0
virtual const tripoint & pos() const =0
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:902
virtual int get_hp_max() const
Definition: creature.cpp:1717
virtual int posx() const =0
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5131
direction direction_from(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:540
@ AEP_SNAKES
Definition: enums.h:109
constexpr double MAX_RECOIL
@ MF_GRABS
Definition: mtype.h:76
bool snake(const tripoint &p, Creature *c, item *i)
Definition: trapfunc.cpp:1428
static constexpr point point_zero
Definition: point.h:260
void add_damage(damage_type dt, float amt, float arpen=0.0f, float arpen_mult=1.0f, float dmg_mult=1.0f)
Adds damage to the instance.
Definition: damage.cpp:41
int type_damage(damage_type dt) const
Definition: damage.cpp:172
int total_damage() const
Definition: damage.cpp:180

References _, scrollingcombattext::add(), damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SNAKES, body_part_name(), bp_torso, Creature::deal_damage(), debugmsg, direction_from(), Creature::disp_name(), disp_name(), DT_ACID, DT_BASH, DT_CUT, DT_STAB, effect_bite, effect_blind, effect_grabbed, effect_grabbing, effect_infected, g, get_dex(), Creature::get_effect_int(), get_hp_bar(), Creature::get_hp_max(), has_artifact_with(), Creature::has_effect(), Creature::has_flag(), has_grab_break_tec(), has_trait(), Creature::is_hallucination(), Creature::is_player(), m_bad, m_good, m_info, m_neutral, m_warning, MAX_RECOIL, MF_GRABS, mon_player_blob, mon_shadow_snake, num_bp, on_hurt(), one_in(), point_zero, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), primary_weapon(), recoil, rl_dist(), rng(), SCT, trapfunc::snake(), dealt_damage_instance::total_damage(), trait_ACIDBLOOD, trait_DEBUG_NODMG, trait_SLIMESPAWNER, dealt_damage_instance::type_damage(), item::volume(), worn, and x_in_y().

Referenced by mattack::bio_op_impale(), mattack::bio_op_takedown(), explosion_handler::ExplosionProcess::blast_tile(), map::burn_body_part(), map::crush(), trapfunc::dissector(), map::drop_furniture(), eff_fun_onfire(), trapfunc::goo(), hitall(), impact(), knock_back_to(), game::knockback(), trapfunc::lava(), explosion_handler::legacy_blast(), melee_special_effects(), petfood(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), map::player_in_field(), smash(), trapfunc::snare_heavy(), and mattack::thrown_by_judo().

◆ defer_move()

bool Character::defer_move ( const tripoint next)

Definition at line 10572 of file character.cpp.

10573{
10574 // next must be adjacent to current pos
10575 if( square_dist( next, pos() ) != 1 ) {
10576 return false;
10577 }
10578 // next must be adjacent to subsequent move in any preexisting automove route
10579 if( has_destination() && square_dist( auto_move_route.front(), next ) != 1 ) {
10580 return false;
10581 }
10582 auto_move_route.insert( auto_move_route.begin(), next );
10584 return true;
10585}
bool has_destination() const
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505

References auto_move_route, has_destination(), next_expected_position, pos(), and square_dist().

Referenced by avatar_action::move().

◆ did_hit()

void Character::did_hit ( Creature target)

Handles special effects when the Character hits a Creature.

Definition at line 8298 of file character.cpp.

8299{
8300 enchantment_cache->cast_hit_you( *this, target );
8301}

References enchantment_cache.

Referenced by melee_attack().

◆ die()

void Character::die ( Creature killer)
overridevirtual

Empty function.

Should always be overwritten by the appropriate player/NPC/monster version.

Implements Creature.

Reimplemented in npc.

Definition at line 3550 of file character.cpp.

3551{
3552 g->set_critter_died();
3553 set_killer( nkiller );
3555 if( has_effect( effect_lightsnare ) ) {
3558 }
3559 if( has_effect( effect_heavysnare ) ) {
3562 }
3563 if( has_effect( effect_beartrap ) ) {
3565 }
3567}
static const itype_id itype_string_36("string_36")
static const efftype_id effect_lightsnare("lightsnare")
static const itype_id itype_snare_trigger("snare_trigger")
static const itype_id itype_beartrap("beartrap")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_heavysnare("heavysnare")
static const itype_id itype_rope_6("rope_6")
void set_time_died(const time_point &time)
set the turn the turn the character died if not already done
Definition: character.h:1477
static void on_creature_death(Creature &poor_dead_dude)
various callbacks from events that may affect all missions
Definition: mission.cpp:132

References inventory::add_item(), effect_beartrap, effect_heavysnare, effect_lightsnare, g, Creature::has_effect(), inv, itype_beartrap, itype_rope_6, itype_snare_trigger, itype_string_36, mission::on_creature_death(), Creature::set_killer(), set_time_died(), calendar::start_of_cataclysm, and calendar::turn.

Referenced by debug_menu::debug(), and npc::die().

◆ dismount()

void Character::dismount ( )

Definition at line 1186 of file character.cpp.

1187{
1188 if( !is_mounted() ) {
1189 add_msg( m_debug, "dismount called when not riding" );
1190 return;
1191 }
1192 if( const std::optional<tripoint> pnt = choose_adjacent( _( "Dismount where?" ) ) ) {
1193 if( !g->is_empty( *pnt ) ) {
1194 add_msg( m_warning, _( "You cannot dismount there!" ) );
1195 return;
1196 }
1198 monster *critter = mounted_creature.get();
1199 critter->mounted_player_id = character_id();
1200 item &weapon = primary_weapon();
1201 if( critter->has_flag( MF_RIDEABLE_MECH ) && !critter->type->mech_weapon.is_empty() &&
1202 weapon.typeId() == critter->type->mech_weapon ) {
1203 remove_item( weapon );
1204 }
1205 if( is_avatar() && g->u.get_grab_type() != OBJECT_NONE ) {
1206 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1207 g->u.grab( OBJECT_NONE );
1208 }
1209 critter->remove_effect( effect_ridden );
1210 critter->add_effect( effect_ai_waiting, 5_turns );
1211 mounted_creature = nullptr;
1212 critter->mounted_player = nullptr;
1213 setpos( *pnt );
1214 mod_moves( -100 );
1216 }
1217}
static const efftype_id effect_ai_waiting("ai_waiting")
static const efftype_id effect_riding("riding")
static const efftype_id effect_ridden("ridden")
void setpos(const tripoint &p) override
Definition: character.h:813
virtual void set_movement_mode(character_movemode mode)=0
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1861
Character * mounted_player
Definition: monster.h:458
character_id mounted_player_id
Definition: monster.h:459
item remove_item(item &it)
Removes and returns the item which must be contained by this instance.
Definition: visitable.cpp:565
@ OBJECT_NONE
Definition: enums.h:187

References _, monster::add_effect(), add_msg(), character_id, choose_adjacent(), CMM_WALK, effect_ai_waiting, effect_ridden, effect_riding, g, monster::has_flag(), Creature::is_avatar(), string_id< T >::is_empty(), is_mounted(), m_debug, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player, monster::mounted_player_id, OBJECT_NONE, primary_weapon(), Creature::remove_effect(), visitable< Character >::remove_item(), set_movement_mode(), setpos(), monster::type, and item::typeId().

Referenced by game::handle_action().

◆ disp_name()

std::string Character::disp_name ( bool  possessive = false,
bool  capitalize_first = false 
) const
overridevirtual

Returns either "you" or the player's name.

capitalize_first assumes that the character's name is already upper case and uses it only for possessive "your" and "you"

Implements Creature.

Definition at line 580 of file character.cpp.

581{
582 if( !possessive ) {
583 if( is_player() ) {
584 return capitalize_first ? _( "You" ) : _( "you" );
585 }
586 return name;
587 } else {
588 if( is_player() ) {
589 return capitalize_first ? _( "Your" ) : _( "your" );
590 }
591 return string_format( _( "%s's" ), name );
592 }
593}

References _, Creature::is_player(), name, and string_format().

Referenced by activate_bionic(), activity_on_turn_move_loot(), add_addiction(), iuse::artifact(), talk_function::assign_camp(), iexamine::autodoc(), best_installer(), bionics_install_failure(), activity_handlers::build_do_turn(), can_uninstall_bionic(), npc::character_danger(), game::chat(), check_and_recover_morale(), check_outbounds_activity(), complete_construction(), deal_damage(), faction_manager::display(), npc::do_npc_read(), npc::do_player_activity(), avatar::do_read(), npc::execute_action(), fetch_activity(), npc::finish_read(), talk_function::goto_location(), npc::handle_sound(), npc::heal_player(), npc::heal_self(), install_bionics(), game::list_missions(), npc::method_of_attack(), talk_function::morale_chat(), talk_function::morale_chat_activity(), npc::mutiny(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_operate(), monster::nursebot_operate(), on_hit(), npc::on_load(), npc::pretend_fire(), npc::pretend_heal(), monster::print_info(), npc::reach_omt_destination(), avatar::read(), game_menus::inv::read(), requirements_map(), talk_effect_fun_t::set_consume_item(), npc::set_fac(), npc::set_known_to_u(), talk_function::start_camp(), character_funcs::try_uncanny_dodge(), uninstall_bionic(), trading_window::update_win(), musical_instrument_actor::use(), heal_actor::use_healing_item(), npc::use_painkiller(), and npc::wield_better_weapon().

◆ dispose_item()

bool Character::dispose_item ( item_location &&  obj,
const std::string &  prompt = std::string() 
)
virtual

Drop, wear, stash or otherwise try to dispose of an item consuming appropriate moves.

Parameters
objitem to dispose of
promptoptional message to display in any menu
Returns
whether the item was successfully disposed of

Reimplemented in npc.

Definition at line 7270 of file character.cpp.

7271{
7272 uilist menu;
7273 menu.text = prompt.empty() ? string_format( _( "Dispose of %s" ), obj->tname() ) : prompt;
7274
7275 using dispose_option = struct {
7276 std::string prompt;
7277 bool enabled;
7278 char invlet;
7279 int moves;
7280 std::function<bool()> action;
7281 };
7282
7283 std::vector<dispose_option> opts;
7284
7285 const bool bucket = obj->is_bucket_nonempty();
7286
7287 opts.emplace_back( dispose_option{
7288 bucket ? _( "Spill contents and store in inventory" ) : _( "Store in inventory" ),
7289 volume_carried() + obj->volume() <= volume_capacity(), '1',
7290 item_handling_cost( *obj ),
7291 [this, bucket, &obj] {
7292 if( bucket && !obj->spill_contents( *this ) )
7293 {
7294 return false;
7295 }
7296
7297 moves -= item_handling_cost( *obj );
7298 inv.add_item_keep_invlet( *obj );
7299 inv.unsort();
7300 obj.remove_item();
7301 return true;
7302 }
7303 } );
7304
7305 opts.emplace_back( dispose_option{
7306 _( "Drop item" ), true, '2', 0, [this, &obj] {
7308 obj.remove_item();
7309 return true;
7310 }
7311 } );
7312
7313 opts.emplace_back( dispose_option{
7314 bucket ? _( "Spill contents and wear item" ) : _( "Wear item" ),
7315 can_wear( *obj ).success(), '3', item_wear_cost( *obj ),
7316 [this, bucket, &obj] {
7317 if( bucket && !obj->spill_contents( *this ) )
7318 {
7319 return false;
7320 }
7321
7322 item it = *obj;
7323 obj.remove_item();
7324 return !!wear_item( it );
7325 }
7326 } );
7327
7328 for( auto &e : worn ) {
7329 if( e.can_holster( *obj ) ) {
7330 auto ptr = dynamic_cast<const holster_actor *>( e.type->get_use( "holster" )->get_actor_ptr() );
7331 opts.emplace_back( dispose_option{
7332 string_format( _( "Store in %s" ), e.tname() ), true, e.invlet,
7333 item_store_cost( *obj, e, false, ptr->draw_cost ),
7334 [this, ptr, &e, &obj] {
7335 return ptr->store( *this->as_player(), e, *obj );
7336 }
7337 } );
7338 }
7339 }
7340
7341 int w = utf8_width( menu.text, true ) + 4;
7342 for( const auto &e : opts ) {
7343 w = std::max( w, utf8_width( e.prompt, true ) + 4 );
7344 }
7345 for( auto &e : opts ) {
7346 e.prompt += std::string( w - utf8_width( e.prompt, true ), ' ' );
7347 }
7348
7349 menu.text.insert( 0, 2, ' ' ); // add space for UI hotkeys
7350 menu.text += std::string( w + 2 - utf8_width( menu.text, true ), ' ' );
7351 menu.text += _( " | Moves " );
7352
7353 for( const auto &e : opts ) {
7354 menu.addentry( -1, e.enabled, e.invlet, string_format( e.enabled ? "%s | %-7d" : "%s |",
7355 e.prompt, e.moves ) );
7356 }
7357
7358 menu.query();
7359 if( menu.ret >= 0 ) {
7360 return opts[menu.ret].action();
7361 }
7362 return false;
7363}
int item_handling_cost(const item &it, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when handling (e.g.
Definition: character.cpp:7477
std::optional< std::list< item >::iterator > wear_item(const item &to_wear, bool interactive=true)
Wear a copy of specified item.
Definition: character.cpp:2129
int item_wear_cost(const item &it) const
Calculate (but do not deduct) the number of moves required to wear an item.
Definition: character.cpp:7517
int item_store_cost(const item &it, const item &container, bool penalties=true, int base_cost=INVENTORY_HANDLING_PENALTY) const
Calculate (but do not deduct) the number of moves required when storing an item in a container.
Definition: character.cpp:7502
ret_val< bool > can_wear(const item &it, bool with_equip_change=false) const
Check character capable of wearing an item.
Definition: character.cpp:2762
Holster a weapon.
Definition: iuse_actor.h:842
void add_item_keep_invlet(item newit)
Definition: inventory.cpp:386
void remove_item()
Removes the selected item from the game.
bool spill_contents(Character &c)
Unloads the item's contents.
Definition: item.cpp:7069
bool is_bucket_nonempty() const
Definition: item.cpp:6755
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
@ prompt
Definition: pickup.h:30

References _, action, inventory::add_item_keep_invlet(), uilist::addentry(), Creature::as_player(), can_wear(), deliberate, enabled, inv, item_handling_cost(), item_store_cost(), item_wear_cost(), Creature::moves, pickup::prompt, ptr(), put_into_vehicle_or_drop(), uilist::query(), visitable< T >::remove_item(), uilist::ret, string_format(), uilist::text, inventory::unsort(), utf8_width(), volume_capacity(), volume_carried(), wear_item(), and worn.

Referenced by activate_bionic(), item::reload(), and unwield().

◆ do_damage_for_bionic_failure()

void Character::do_damage_for_bionic_failure ( int  min_damage,
int  max_damage 
)

Definition at line 2408 of file bionics.cpp.

2409{
2410 std::set<bodypart_id> bp_hurt;
2411 for( const bodypart_id &bp : get_all_body_parts() ) {
2412 if( has_effect( effect_under_op, bp->token ) ) {
2413 if( bp_hurt.count( bp->main_part ) > 0 ) {
2414 continue;
2415 }
2416 bp_hurt.emplace( bp->main_part );
2417 }
2418 }
2419
2420 if( bp_hurt.empty() ) {
2421 // If no bodypart associetd with bionic- just damage torso.
2422 // Special check for power storage - it does not belong to any body part.
2423 bp_hurt.emplace( bodypart_str_id( "torso" ) );
2424 }
2425
2426 for( const bodypart_id &bp : bp_hurt ) {
2427 int damage = rng( min_damage, max_damage );
2428 int hp = get_hp( bp );
2429 if( damage >= hp && ( bp == bodypart_str_id( "head" ) || bp == bodypart_str_id( "torso" ) ) ) {
2430 add_effect( effect_infected, 1_hours, bp->token );
2431 add_msg_player_or_npc( m_bad, _( "Your %s is infected." ), _( "<npcname>'s %s is infected." ),
2433 damage = hp * 0.8f;
2434 }
2435 apply_damage( this, bp, damage, true );
2436 if( damage > 15 )
2437 add_msg_player_or_npc( m_bad, _( "Your %s is severely damaged." ),
2438 _( "<npcname>'s %s is severely damaged." ),
2440 else
2441 add_msg_player_or_npc( m_bad, _( "Your %s is damaged." ), _( "<npcname>'s %s is damaged." ),
2443
2444 }
2445}
static const efftype_id effect_under_op("under_operation")
static const efftype_id effect_infected("infected")
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:331
virtual int get_hp() const
Definition: creature.cpp:1700

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), body_part_name_accusative(), effect_infected, effect_under_op, Creature::get_all_body_parts(), Creature::get_hp(), Creature::has_effect(), hp, m_bad, and rng().

Referenced by bionics_install_failure(), and bionics_uninstall_failure().

◆ do_skill_rust()

void Character::do_skill_rust ( )
protected

Definition at line 3600 of file character.cpp.

3601{
3602 const int rust_rate_tmp = rust_rate();
3603 static const std::string PRED2( "PRED2" );
3604 static const std::string PRED3( "PRED3" );
3605 static const std::string PRED4( "PRED4" );
3606 for( std::pair<const skill_id, SkillLevel> &pair : *_skills ) {
3607 const Skill &aSkill = *pair.first;
3608 SkillLevel &skill_level_obj = pair.second;
3609
3610 if( aSkill.is_combat_skill() &&
3611 ( ( has_trait_flag( PRED2 ) && calendar::once_every( 8_hours ) ) ||
3612 ( has_trait_flag( PRED3 ) && calendar::once_every( 4_hours ) ) ||
3613 ( has_trait_flag( PRED4 ) && calendar::once_every( 3_hours ) ) ) ) {
3614 // Their brain is optimized to remember this
3615 if( one_in( 13 ) ) {
3616 // They've already passed the roll to avoid rust at
3617 // this point, but print a message about it now and
3618 // then.
3619 //
3620 // 13 combat skills.
3621 // This means PRED2/PRED3/PRED4 think of hunting on
3622 // average every 8/4/3 hours, enough for immersion
3623 // without becoming an annoyance.
3624 //
3625 add_msg_if_player( _( "Your heart races as you recall your most recent hunt." ) );
3626 mod_stim( 1 );
3627 }
3628 continue;
3629 }
3630
3631 const bool charged_bio_mem = get_power_level() > bio_memory->power_trigger &&
3633 const int oldSkillLevel = skill_level_obj.level();
3634 if( skill_level_obj.rust( charged_bio_mem, rust_rate_tmp ) ) {
3636 _( "Your knowledge of %s begins to fade, but your memory banks retain it!" ), aSkill.name() );
3638 }
3639 const int newSkill = skill_level_obj.level();
3640 if( newSkill < oldSkillLevel ) {
3641 add_msg_if_player( m_bad, _( "Your skill in %s has reduced to %d!" ), aSkill.name(), newSkill );
3642 }
3643 }
3644}
bool has_trait_flag(const std::string &b) const
Returns true if player has a trait with a flag.
Definition: mutation.cpp:106
int rust_rate() const
Returns the player's skill rust rate.
Definition: character.cpp:3394
void mod_stim(int mod)
Definition: character.cpp:7070
int level() const
Definition: skill.h:125
bool rust(bool charged_bio_mem, int character_rate)
Definition: skill.cpp:269
Definition: skill.h:33
std::string name() const
Definition: skill.h:68
bool is_combat_skill() const
Definition: skill.cpp:211
units::energy power_trigger
Power cost when the bionic's special effect is triggered.
Definition: bionics.h:43

References _, _skills, Creature::add_msg_if_player(), bio_memory, get_power_level(), has_active_bionic(), has_trait_flag(), Skill::is_combat_skill(), SkillLevel::level(), m_bad, m_warning, mod_power_level(), mod_stim(), Skill::name(), calendar::once_every(), one_in(), bionic_data::power_trigger, SkillLevel::rust(), and rust_rate().

Referenced by update_body().

◆ dodge_roll()

float Character::dodge_roll ( )
overridevirtual

Implements Creature.

Definition at line 909 of file melee.cpp.

910{
911 return get_dodge() * 5;
912}
float get_dodge() const override
Definition: melee.cpp:866

References get_dodge().

◆ drench()

void Character::drench ( int  saturation,
const body_part_set flags,
bool  ignore_waterproof 
)

Drenches the player with water, saturation is the percent gotten wet.

Definition at line 1709 of file suffer.cpp.

1710{
1711 if( saturation < 1 ) {
1712 return;
1713 }
1714
1715 // OK, water gets in your AEP suit or whatever. It wasn't built to keep you dry.
1717 ( !ignore_waterproof && is_waterproof( flags ) ) ) {
1718 return;
1719 }
1720
1721 // Make the body wet
1722 for( const body_part bp : all_body_parts ) {
1723 // Different body parts have different size, they can only store so much water
1724 int bp_wetness_max = 0;
1725 if( flags.test( bp ) ) {
1726 bp_wetness_max = drench_capacity[bp];
1727 }
1728
1729 if( bp_wetness_max == 0 ) {
1730 continue;
1731 }
1732 // Different sources will only make the bodypart wet to a limit
1733 int source_wet_max = saturation * bp_wetness_max * 2 / 100;
1734 int wetness_increment = ignore_waterproof ? 100 : 2;
1735 // Respect maximums
1736 const int wetness_max = std::min( source_wet_max, bp_wetness_max );
1737 if( body_wetness[bp] < wetness_max ) {
1738 body_wetness[bp] = std::min( wetness_max, body_wetness[bp] + wetness_increment );
1739 }
1740 }
1741
1744 get_value( "waterproof_scent" ).empty() ) {
1745 add_msg_if_player( m_info, _( "The water wash away the scent." ) );
1746 restore_scent();
1747 }
1748
1749 if( is_weak_to_water() ) {
1750 add_msg_if_player( m_bad, _( "You feel the water burning your skin." ) );
1751 }
1752
1753 // Remove onfire effect
1754 if( saturation > 10 || x_in_y( saturation, 10 ) ) {
1756 }
1757}
bool is_waterproof(const body_part_set &parts) const
Definition: character.cpp:9002
bool is_weak_to_water() const
Definition: mutation.cpp:412
void restore_scent()
restore scent after masked_scent effect run out or is removed by water
Definition: character.cpp:8771
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_SHELL2("SHELL2")
static const efftype_id effect_onfire("onfire")

References _, Creature::add_msg_if_player(), all_body_parts, body_wetness, bp_torso, drench_capacity, effect_masked_scent, effect_onfire, Creature::get_value(), has_active_mutation(), Creature::has_effect(), has_trait(), is_waterproof(), is_weak_to_water(), m_bad, m_info, Creature::remove_effect(), restore_scent(), body_part_set::test(), trait_DEBUG_NOTEMP, trait_SHELL2, and x_in_y().

Referenced by character_funcs::do_pause(), game::place_player(), and avatar_action::swim().

◆ drench_mut_calc()

void Character::drench_mut_calc ( )

Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)

Definition at line 7823 of file character.cpp.

7824{
7825 for( const body_part bp : all_body_parts ) {
7826 int ignored = 0;
7827 int neutral = 0;
7828 int good = 0;
7829
7830 for( const trait_id &iter : get_mutations() ) {
7831 const mutation_branch &mdata = iter.obj();
7832 const auto wp_iter = mdata.protection.find( bp );
7833 if( wp_iter != mdata.protection.end() ) {
7834 ignored += wp_iter->second.x;
7835 neutral += wp_iter->second.y;
7836 good += wp_iter->second.z;
7837 }
7838 }
7839
7840 mut_drench[bp][WT_GOOD] = good;
7842 mut_drench[bp][WT_IGNORED] = ignored;
7843 }
7844}
@ good
Item should display as green (action possible at the moment)
std::map< body_part, tripoint > protection
Definition: mutation.h:269

References all_body_parts, get_mutations(), mut_drench, neutral, mutation_branch::protection, WT_GOOD, WT_IGNORED, and WT_NEUTRAL.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ drop() [1/2]

void Character::drop ( const drop_locations what,
const tripoint target,
bool  stash = false 
)
virtual

Reimplemented in npc.

Definition at line 2475 of file character.cpp.

2477{
2478 if( what.empty() ) {
2479 return;
2480 }
2481
2482 if( rl_dist( pos(), target ) > 1 || !( stash || get_map().can_put_items( target ) ) ) {
2483 add_msg_player_or_npc( m_info, _( "You can't place items here!" ),
2484 _( "<npcname> can't place items here!" ) );
2485 return;
2486 }
2487
2488 if( stash ) {
2489 assign_activity( stash_activity_actor( *this, what, target - pos() ) );
2490 } else {
2491 assign_activity( drop_activity_actor( *this, what, false, target - pos() ) );
2492 }
2493}

References _, Creature::add_msg_player_or_npc(), assign_activity(), get_map(), m_info, pos(), and rl_dist().

◆ drop() [2/2]

void Character::drop ( item_location  loc,
const tripoint where 
)

Drops an item to the specified location.

Definition at line 2453 of file character.cpp.

2454{
2455 item &oThisItem = *loc;
2456 if( is_wielding( oThisItem ) ) {
2457 const auto ret = can_unwield( *loc );
2458
2459 if( !ret.success() ) {
2460 add_msg( m_info, "%s", ret.c_str() );
2461 return;
2462 }
2463 } else if( is_wearing( oThisItem ) ) {
2464 const auto ret = as_player()->can_takeoff( *loc );
2465
2466 if( !ret.success() ) {
2467 add_msg( m_info, "%s", ret.c_str() );
2468 return;
2469 }
2470 }
2471
2472 drop( { drop_location( loc, loc->count() ) }, where );
2473}
ret_val< bool > can_takeoff(const item &it, const std::list< item > *res=nullptr) const
Check if character is capable of taking off given item.
Definition: character.cpp:3022
void drop(item_location loc, const tripoint &where)
Drops an item to the specified location.
Definition: character.cpp:2453
iuse_location drop_location

References add_msg(), Creature::as_player(), can_takeoff(), can_unwield(), item::count(), drop(), is_wearing(), is_wielding(), m_info, and cata::hash64_detail::ret.

Referenced by game::drop(), npc::drop(), drop(), game::drop_in_direction(), monexamine::give_items_to(), harvest_common(), i_add_or_drop(), examine_item_menu::run(), suffer_from_schizophrenia(), and takeoff().

◆ drop_invalid_inventory()

void Character::drop_invalid_inventory ( )

Definition at line 3191 of file character.cpp.

3192{
3193 bool dropped_liquid = false;
3194 for( const std::list<item> *stack : inv.const_slice() ) {
3195 const item &it = stack->front();
3196 if( it.made_of( LIQUID ) ) {
3197 dropped_liquid = true;
3198 get_map().add_item_or_charges( pos(), it );
3199 // must be last
3200 i_rem( &it );
3201 }
3202 }
3203 if( dropped_liquid ) {
3204 add_msg_if_player( m_bad, _( "Liquid from your inventory has leaked onto the ground." ) );
3205 }
3206
3207 if( volume_carried() > volume_capacity() ) {
3208 auto items_to_drop = inv.remove_randomly_by_volume( volume_carried() - volume_capacity() );
3210 }
3211}
std::list< item > remove_randomly_by_volume(const units::volume &volume)
Randomly select items until the volume quota is filled.
Definition: inventory.cpp:759
const_invslice const_slice() const
Definition: inventory.cpp:144
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4355

References _, map::add_item_or_charges(), Creature::add_msg_if_player(), inventory::const_slice(), get_map(), i_rem(), inv, LIQUID, m_bad, item::made_of(), pos(), put_into_vehicle_or_drop(), inventory::remove_randomly_by_volume(), tumbling, volume_capacity(), and volume_carried().

Referenced by absorb_hit(), player_activity::do_turn(), npc::execute_action(), process_turn(), and npc_trading::trade().

◆ eat()

bool Character::eat ( item food,
bool  force = false 
)

Used for eating entered comestible, returns true if comestible is successfully eaten.

Definition at line 828 of file consumption.cpp.

829{
830 if( !food.is_food() ) {
831 return false;
832 }
833
834 const auto ret = force ? can_eat( food ) : will_eat( food, is_player() );
835 if( !ret.success() ) {
836 return false;
837 }
838
839 if( has_effect( effect_bloated ) &&
840 ( compute_effective_nutrients( food ).kcal > 0 || food.get_comestible()->quench > 0 ) &&
841 !food.has_flag( flag_NO_BLOAT ) ) {
842 add_msg_if_player( _( "You force yourself to vomit to make space for %s." ), food.tname() );
843 vomit();
844 }
845
846 int charges_used = 0;
847 if( food.type->has_use() ) {
848 if( !food.type->can_use( "DOGFOOD" ) &&
849 !food.type->can_use( "CATFOOD" ) &&
850 !food.type->can_use( "BIRDFOOD" ) &&
851 !food.type->can_use( "CATTLEFODDER" ) ) {
852 charges_used = food.type->invoke( *this->as_player(), food, pos() );
853 if( charges_used <= 0 ) {
854 return false;
855 }
856 }
857 }
858
859 // Note: the block below assumes we decided to eat it
860 // No coming back from here
861
862 const int nutr = nutrition_for( food );
863 const bool spoiled = food.rotten();
864
865 // The item is solid food
866 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
868 // This item is a drink and not a solid food (and not a thick soup)
869 const bool drinkable = !chew && food.get_comestible()->comesttype == comesttype_DRINK;
870 // If neither of the above is true then it's a drug and shouldn't get mealtime penalty/bonus
871
872 const bool saprophage = has_trait( trait_SAPROPHAGE );
873 if( spoiled && !saprophage ) {
874 add_msg_if_player( m_bad, _( "Ick, this %s doesn't taste so good…" ), food.tname() );
877 add_effect( effect_foodpoison, rng( 6_minutes, ( nutr + 1 ) * 6_minutes ) );
878 }
879 } else if( spoiled && saprophage ) {
880 add_msg_if_player( m_good, _( "Mmm, this %s tastes delicious…" ), food.tname() );
881 }
882 // Store the fact that the food was cold to later reapply it to the rest of the stack, to prevent rot.
883 // Note: Implemented to fix display error when eating reheated food.
884 bool food_was_cold = food.has_flag( flag_COLD );
885 bool food_was_very_cold = food.has_flag( flag_VERY_COLD );
886
887 if( !consume_effects( food ) ) {
888 // Already consumed by using `food.type->invoke`?
889 if( charges_used > 0 ) {
890 food.mod_charges( -charges_used );
891 }
892 return false;
893 }
894 food.mod_charges( -1 );
895
896 const bool amorphous = has_trait( trait_AMORPHOUS );
897 int mealtime = 250;
898 if( drinkable || chew ) {
899 // Those bonuses/penalties only apply to food
900 // Not to smoking weed or applying bandages!
903 mealtime /= 2;
904 } else if( has_trait( trait_SHARKTEETH ) ) {
905 // SHARKBAIT! HOO HA HA!
906 mealtime /= 3;
907 } else if( has_trait( trait_GOURMAND ) ) {
908 // Don't stack those two - that would be 25 moves per item
909 mealtime -= 100;
910 }
911
912 if( has_trait( trait_BEAK_HUM ) && !drinkable ) {
913 // Much better than PROBOSCIS but still optimized for fluids
914 mealtime += 200;
915 } else if( has_trait( trait_SABER_TEETH ) ) {
916 // They get In The Way
917 mealtime += 250;
918 }
919
920 if( amorphous ) {
921 mealtime *= 1.1;
922 // Minor speed penalty for having to flow around it
923 // rather than just grab & munch
924 }
925 }
926
927 moves -= mealtime;
928
929 // If it's poisonous... poison us.
930 // TODO: Move this to a flag
931 if( food.poison > 0 && !has_trait( trait_POISRESIST ) &&
933 if( food.poison >= rng( 2, 4 ) ) {
934 add_effect( effect_poison, food.poison * 10_minutes );
935 }
936
937 add_effect( effect_foodpoison, food.poison * 30_minutes );
938 }
939
940 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
941 if( !has_effect( effect_hallu ) ) {
942 add_effect( effect_hallu, 6_hours );
943 }
944 }
945
946 if( amorphous ) {
947 add_msg_player_or_npc( _( "You assimilate your %s." ), _( "<npcname> assimilates a %s." ),
948 food.tname() );
949 } else if( drinkable ) {
950 add_msg_player_or_npc( _( "You drink your %s." ), _( "<npcname> drinks a %s." ),
951 food.tname() );
952 } else if( chew ) {
953 add_msg_player_or_npc( _( "You eat your %s." ), _( "<npcname> eats a %s." ),
954 food.tname() );
955 }
956
957 if( food_was_cold ) {
958 food.set_flag( flag_COLD );
959 }
960
961 if( food_was_very_cold ) {
962 food.set_flag( flag_VERY_COLD );
963 }
964
965 if( food.get_comestible()->tool->tool ) {
966 // Tools like lighters get used
967 use_charges( food.get_comestible()->tool, 1 );
968 }
969
971 add_effect( effect_fungus, 1_turns, num_bp );
972 }
973
974 // Chance to become parasitised
976 if( food.get_comestible()->parasites > 0 && !food.has_flag( flag_NO_PARASITES ) &&
977 one_in( food.get_comestible()->parasites ) ) {
978 switch( rng( 0, 3 ) ) {
979 case 0:
980 add_effect( effect_tapeworm, 1_turns, num_bp );
981 break;
982 case 1:
983 if( !has_trait( trait_ACIDBLOOD ) ) {
985 }
986 break;
987 case 2:
989 break;
990 case 3:
992 }
993 }
994 }
995
996 for( const std::pair<const diseasetype_id, int> &elem : food.get_comestible()->contamination ) {
997 if( rng( 1, 100 ) <= elem.second ) {
998 expose_to_disease( elem.first );
999 }
1000 }
1001
1002 consumption_history->elems.emplace_back( food );
1003 // Clean out consumption_history so it doesn't get bigger than needed.
1004 while( consumption_history->elems.front().time < calendar::turn - 2_days ) {
1005 consumption_history->elems.pop_front();
1006 }
1007
1008 return true;
1009}
void expose_to_disease(diseasetype_id dis_type)
Determine if character is susceptible to dis_type and if so apply the symptoms.
Definition: character.cpp:1565
pimpl< consumption_history_t > consumption_history
Definition: character.h:1589
ret_val< edible_rating > will_eat(const item &food, bool interactive=false) const
Same as can_eat, but takes consequences into account.
bool rotten() const
returns true if item is now rotten after all shelf life has elapsed
Definition: item.h:849
void mod_charges(int mod)
Modify the charges of this item, only use for items counted by charges! The item must have enough cha...
Definition: item.cpp:9728
int poison
Definition: item.h:2214
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5359
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const std::string flag_FUNGAL_VECTOR("FUNGAL_VECTOR")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_EATDEAD("EATDEAD")
static const trait_id trait_SABER_TEETH("SABER_TEETH")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_hallu("hallu")
static const std::string flag_VERY_COLD("VERY_COLD")
static const trait_id trait_BEAK_HUM("BEAK_HUM")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const trait_id trait_MANDIBLES("MANDIBLES")
static const std::string flag_HIDDEN_HALLU("HIDDEN_HALLU")
static const efftype_id effect_paincysts("paincysts")
static const std::string flag_NO_PARASITES("NO_PARASITES")
static const trait_id trait_AMORPHOUS("AMORPHOUS")
static const trait_id trait_MOUTH_TENTACLES("MOUTH_TENTACLES")
static const efftype_id effect_poison("poison")
static const std::string flag_COLD("COLD")
static const efftype_id effect_foodpoison("foodpoison")
static const trait_id trait_FANGS_SPIDER("FANGS_SPIDER")
static const trait_id trait_POISRESIST("POISRESIST")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
int chew(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1105

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), Creature::as_player(), bio_digestion, can_eat(), itype::can_use(), iuse::chew(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), consume_effects(), consumption_history, effect_bloated, effect_bloodworms, effect_brainworms, effect_foodpoison, effect_fungus, effect_hallu, effect_paincysts, effect_poison, effect_tapeworm, expose_to_disease(), flag_COLD(), flag_FUNGAL_VECTOR(), flag_HIDDEN_HALLU(), flag_NO_BLOAT(), flag_NO_PARASITES(), flag_USE_EAT_VERB(), flag_VERY_COLD(), item::get_comestible(), has_bionic(), Creature::has_effect(), item::has_flag(), has_trait(), itype::has_use(), itype::invoke(), item::is_food(), Creature::is_player(), m_bad, m_good, item::mod_charges(), Creature::moves, num_bp, nutrition_for(), one_in(), item::poison, pos(), cata::hash64_detail::ret, rng(), item::rotten(), item::set_flag(), item::tname(), trait_ACIDBLOOD, trait_AMORPHOUS, trait_BEAK_HUM, trait_EATDEAD, trait_FANGS_SPIDER, trait_GOURMAND, trait_M_IMMUNE, trait_MANDIBLES, trait_MOUTH_TENTACLES, trait_PARAIMMUNE, trait_POISRESIST, trait_SABER_TEETH, trait_SAPROPHAGE, trait_SAPROVORE, trait_SHARKTEETH, calendar::turn, item::type, use_charges(), vomit(), and will_eat().

Referenced by consume_item(), drink_nectar(), avatar_action::eat_here(), iexamine::flower_poppy(), vehicle::interact_with(), iexamine::keg(), and try_consume().

◆ encumb()

◆ enforce_minimum_healing()

void Character::enforce_minimum_healing ( )

Definition at line 4649 of file character.cpp.

4650{
4651 for( const bodypart_id &bp : get_all_body_parts() ) {
4652 if( get_part_healed_total( bp ) <= 0 ) {
4653 heal( bp, 1 );
4654 }
4655 set_part_healed_total( bp, 0 );
4656 }
4657}
void heal(const bodypart_id &healed, int dam)
Heals a body_part for dam.
Definition: character.cpp:8648
void set_part_healed_total(const bodypart_id &id, int set)
Definition: creature.cpp:1632
int get_part_healed_total(const bodypart_id &id) const
Definition: creature.cpp:1617

References Creature::get_all_body_parts(), Creature::get_part_healed_total(), heal(), and Creature::set_part_healed_total().

Referenced by update_body().

◆ enough_power_for()

bool Character::enough_power_for ( const bionic_id bid) const

Definition at line 1957 of file character.cpp.

1958{
1959 return power_level >= bid->power_activate;
1960}
units::energy power_level
Definition: character.h:2246

References bionic_data::power_activate, and power_level.

Referenced by activate_bionic(), and iexamine::fireplace().

◆ enumerate_unmet_requirements()

std::string Character::enumerate_unmet_requirements ( const item it,
const item context = item() 
) const

Returns a string of missed requirements (both stats and skills)

Definition at line 3370 of file character.cpp.

3371{
3372 std::vector<std::string> unmet_reqs;
3373
3374 const auto check_req = [ &unmet_reqs ]( const std::string & name, int cur, int req ) {
3375 if( cur < req ) {
3376 unmet_reqs.push_back( string_format( "%s %d", name, req ) );
3377 }
3378 };
3379
3380 check_req( _( "strength" ), get_str(), it.get_min_str() );
3381 check_req( _( "dexterity" ), get_dex(), it.type->min_dex );
3382 check_req( _( "intelligence" ), get_int(), it.type->min_int );
3383 check_req( _( "perception" ), get_per(), it.type->min_per );
3384
3385 for( const auto &elem : it.type->min_skills ) {
3386 check_req( context.contextualize_skill( elem.first )->name(),
3387 get_skill_level( elem.first, context ),
3388 elem.second );
3389 }
3390
3391 return enumerate_as_string( unmet_reqs );
3392}
int get_min_str() const
Definition: item.cpp:10051
skill_id contextualize_skill(const skill_id &id) const
Puts the skill in context of the item.
Definition: item.cpp:9973
int min_dex
Definition: itype.h:909
int min_int
Definition: itype.h:910
int min_per
Definition: itype.h:911
std::map< skill_id, int > min_skills
Definition: itype.h:907

References _, item::contextualize_skill(), enumerate_as_string(), get_dex(), get_int(), item::get_min_str(), get_per(), get_skill_level(), get_str(), itype::min_dex, itype::min_int, itype::min_per, itype::min_skills, name, Skill::name(), string_format(), and item::type.

Referenced by can_use(), and gunmod_inventory_preset::get_denial().

◆ env_surgery_bonus()

float Character::env_surgery_bonus ( int  radius)

Calculate skill bonus from tiles in radius.

Definition at line 2287 of file bionics.cpp.

2288{
2289 float bonus = 1.0;
2290 map &here = get_map();
2291 for( const tripoint &cell : here.points_in_radius( pos(), radius ) ) {
2292 if( here.furn( cell )->surgery_skill_multiplier ) {
2293 bonus = std::max( bonus, *here.furn( cell )->surgery_skill_multiplier );
2294 }
2295 }
2296 return bonus;
2297}

References get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), and pos().

Referenced by bionics_adjusted_skill().

◆ environmental_revert_effect()

void Character::environmental_revert_effect ( )

Definition at line 788 of file character_turn.cpp.

789{
790 addictions.clear();
791 morale->clear();
792
795 set_thirst( 0 );
796 set_fatigue( 0 );
797 set_healthy( 0 );
798 set_healthy_mod( 0 );
799 set_stim( 0 );
800 set_pain( 0 );
801 set_painkiller( 0 );
802 set_rad( 0 );
804
807}
virtual void set_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4474
virtual void set_healthy_mod(int nhealthy_mod)
Definition: character.cpp:4279
virtual void set_stored_kcal(int kcal)
Setters for need values exclusive to characters.
Definition: character.cpp:4335
void set_pain(int npain) override
Sets new intensity of pain an reacts to it.
Definition: character.cpp:791
virtual void set_healthy(int nhealthy)
Setters for health values exclusive to characters.
Definition: character.cpp:4267
virtual void set_thirst(int nthirst)
Definition: character.cpp:4447
void set_all_parts_hp_to_max()
Definition: creature.cpp:1659

References addictions, max_stored_kcal(), morale, recalc_sight_limits(), reset_encumbrance(), Creature::set_all_parts_hp_to_max(), set_fatigue(), set_healthy(), set_healthy_mod(), set_pain(), set_painkiller(), set_rad(), set_sleep_deprivation(), set_stim(), set_stored_kcal(), and set_thirst().

◆ exclusive_flag_coverage()

body_part_set Character::exclusive_flag_coverage ( const std::string &  flag) const

Bitset of all the body parts covered only with items with flag (or nothing)

Definition at line 4069 of file character.cpp.

4070{
4072
4073 for( const auto &elem : worn ) {
4074 if( !elem.has_flag( flag ) ) {
4075 // Unset the parts covered by this item
4076 ret &= ~elem.get_covered_body_parts();
4077 }
4078 }
4079
4080 return ret;
4081}
static body_part_set all()
Definition: bodypart.h:249

References body_part_set::all(), cata::hash64_detail::ret, and worn.

Referenced by apply_wetness_morale(), mut_cbm_encumb(), mutation_attacks(), reset_stats(), and swim_speed().

◆ expose_to_disease()

void Character::expose_to_disease ( diseasetype_id  dis_type)

Determine if character is susceptible to dis_type and if so apply the symptoms.

Definition at line 1565 of file character.cpp.

1566{
1567 const std::optional<int> &healt_thresh = dis_type->health_threshold;
1568 if( healt_thresh && healt_thresh.value() < get_healthy() ) {
1569 return;
1570 }
1571 const std::set<body_part> &bps = dis_type->affected_bodyparts;
1572 if( !bps.empty() ) {
1573 for( const body_part &bp : bps ) {
1574 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), bp,
1575 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1576 }
1577 } else {
1578 add_effect( dis_type->symptoms, rng( dis_type->min_duration, dis_type->max_duration ), num_bp,
1579 rng( dis_type->min_intensity, dis_type->max_intensity ) );
1580 }
1581}
virtual int get_healthy() const
Getters for health values exclusive to characters.
Definition: character.cpp:4166
time_duration min_duration
Definition: disease.h:26
std::optional< int > health_threshold
If not empty this sets the health threshold above which you're immune to the disease.
Definition: disease.h:33
int max_intensity
Definition: disease.h:29
efftype_id symptoms
effect applied by this disease
Definition: disease.h:35
std::set< body_part > affected_bodyparts
Affected body parts.
Definition: disease.h:31
int min_intensity
Definition: disease.h:28
time_duration max_duration
Definition: disease.h:27

References Creature::add_effect(), disease_type::affected_bodyparts, get_healthy(), disease_type::health_threshold, disease_type::max_duration, disease_type::max_intensity, disease_type::min_duration, disease_type::min_intensity, num_bp, rng(), and disease_type::symptoms.

Referenced by eat().

◆ extended_description()

std::string Character::extended_description ( ) const
overridevirtual

Implements Creature.

Reimplemented in npc.

Definition at line 6507 of file character.cpp.

6508{
6509 std::string ss;
6510 if( is_player() ) {
6511 // <bad>This is me, <player_name>.</bad>
6512 ss += string_format( _( "This is you - %s." ), name );
6513 } else {
6514 ss += string_format( _( "This is %s, %s" ), name, male ? _( "Male" ) : _( "Female" ) );
6515 }
6516
6517 ss += "\n--\n";
6518
6519 const std::vector<bodypart_id> &bps = get_all_body_parts( true );
6520 // Find length of bp names, to align
6521 // accumulate looks weird here, any better function?
6522 int longest = std::accumulate( bps.begin(), bps.end(), 0,
6523 []( int m, bodypart_id bp ) {
6524 return std::max( m, utf8_width( body_part_name_as_heading( bp->token, 1 ) ) );
6525 } );
6526
6527 // This is a stripped-down version of the body_window function
6528 // This should be extracted into a separate function later on
6529 for( const bodypart_id &bp : bps ) {
6530 // Hide appendix from the player
6531 if( bp->id.str() == "num_bp" ) {
6532 continue;
6533 }
6534 const std::string &bp_heading = body_part_name_as_heading( bp->token, 1 );
6535
6536 const nc_color state_col = limb_color( bp, true, true, true );
6537 nc_color name_color = state_col;
6538 std::pair<std::string, nc_color> hp_bar = get_hp_bar( get_part_hp_cur( bp ), get_part_hp_max( bp ),
6539 false );
6540
6541 ss += colorize( left_justify( bp_heading, longest ), name_color );
6542 ss += colorize( hp_bar.first, hp_bar.second );
6543 // Trailing bars. UGLY!
6544 // TODO: Integrate into get_hp_bar somehow
6545 ss += colorize( std::string( 5 - utf8_width( hp_bar.first ), '.' ), c_white );
6546 ss += "\n";
6547 }
6548
6549 ss += "--\n";
6550 ss += _( "Wielding:" ) + std::string( " " );
6551 const item &weapon = primary_weapon();
6552 if( weapon.is_null() ) {
6553 ss += _( "Nothing" );
6554 } else {
6555 ss += weapon.tname();
6556 }
6557
6558 ss += "\n";
6559 ss += _( "Wearing:" ) + std::string( " " );
6560 ss += enumerate_as_string( worn.begin(), worn.end(), []( const item & it ) {
6561 return it.tname();
6562 } );
6563
6564 return replace_colors( ss );
6565}
std::string left_justify(const std::string &str, const int width, const bool ignore_tags)
bool male
Definition: character.h:1565
std::string replace_colors(std::string text)
Replace special color tags (e.g.

References _, body_part_name_as_heading(), c_white, colorize(), enumerate_as_string(), Creature::get_all_body_parts(), get_hp_bar(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), int_id< T >::id(), item::is_null(), Creature::is_player(), left_justify(), limb_color(), male, name, primary_weapon(), replace_colors(), string_format(), item::tname(), utf8_width(), and worn.

Referenced by npc::extended_description().

◆ extraEncumbrance()

int Character::extraEncumbrance ( layer_level  level,
int  bp 
) const

Get encumbrance penalty per layer & body part.

Definition at line 3715 of file character.cpp.

3716{
3717 return encumbrance_cache->elems[bp].layer_penalty_details[static_cast<int>( level )].total;
3718}

References encumbrance_cache.

◆ fall_asleep() [1/2]

void Character::fall_asleep ( )

Adds "sleep" to the player.

Definition at line 9279 of file character.cpp.

9280{
9281 // Communicate to the player that he is using items on the floor
9282 std::string item_name = is_snuggling();
9283 if( item_name == "many" ) {
9284 if( one_in( 15 ) ) {
9285 add_msg_if_player( _( "You nestle your pile of clothes for warmth." ) );
9286 } else {
9287 add_msg_if_player( _( "You use your pile of clothes for warmth." ) );
9288 }
9289 } else if( item_name != "nothing" ) {
9290 if( one_in( 15 ) ) {
9291 add_msg_if_player( _( "You snuggle your %s to keep warm." ), item_name );
9292 } else {
9293 add_msg_if_player( _( "You use your %s to keep warm." ), item_name );
9294 }
9295 }
9297 if( get_stored_kcal() > max_stored_kcal() - bmr() / 4 &&
9299 if( is_avatar() ) {
9300 g->memorial().add( pgettext( "memorial_male", "Entered hibernation." ),
9301 pgettext( "memorial_female", "Entered hibernation." ) );
9302 }
9303
9304 add_msg_if_player( _( "You enter hibernation." ) );
9305 fall_asleep( 7_days );
9306 } else {
9308 _( "You need to be nearly full of food and water to enter hibernation." ) );
9309 }
9310 }
9311
9312 fall_asleep( 10_hours ); // default max sleep time.
9313}
static const trait_id trait_HIBERNATE("HIBERNATE")
int bmr() const
Definition: character.cpp:6865
std::string is_snuggling() const
Checks to see if the player is using floor items to keep warm, and return the name of one such item i...
Definition: character.cpp:9332

References _, Creature::add_msg_if_player(), bmr(), fall_asleep(), g, get_stored_kcal(), get_thirst(), has_active_mutation(), Creature::is_avatar(), is_snuggling(), m_bad, max_stored_kcal(), one_in(), pgettext(), thirsty, and trait_HIBERNATE.

Referenced by check_needs_extremes(), fall_asleep(), iexamine::flower_poppy(), hardcoded_effects(), introduce_into_anesthesia(), marloss_common(), iuse::mycus(), process_one_effect(), suffer_from_stimulants(), suffer_while_awake(), try_reject_mutagen(), activity_handlers::try_sleep_do_turn(), and mutagen_iv_actor::use().

◆ fall_asleep() [2/2]

void Character::fall_asleep ( const time_duration duration)

Definition at line 9315 of file character.cpp.

9316{
9317 if( activity ) {
9318 if( activity.id() == ACT_TRY_SLEEP ) {
9320 } else {
9322 }
9323 }
9324 add_effect( effect_sleep, duration );
9325}
void cancel_activity()
Definition: character.cpp:9239
void set_to_null()
This replaces the former usage act.type = ACT_NULL

References ACT_TRY_SLEEP, activity, Creature::add_effect(), cancel_activity(), effect_sleep, player_activity::id(), and player_activity::set_to_null().

◆ fall_damage_mod()

float Character::fall_damage_mod ( ) const
overridevirtual

Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)

Dexterity decreases damage from falling Dodge decreases damage from falling

Implements Creature.

Definition at line 10806 of file character.cpp.

10807{
10808 if( has_effect_with_flag( "EFFECT_FEATHER_FALL" ) ) {
10809 return 0.0f;
10810 }
10811 float ret = 1.0f;
10812
10813 // Ability to land properly is 2x as important as dexterity itself
10814 /** @EFFECT_DEX decreases damage from falling */
10815
10816 /** @EFFECT_DODGE decreases damage from falling */
10817 float dex_dodge = dex_cur / 2.0 + get_skill_level( skill_dodge );
10818 // Penalize for wearing heavy stuff
10819 const float average_leg_encumb = ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 2.0;
10820 dex_dodge -= ( average_leg_encumb + encumb( bp_torso ) ) / 10;
10821 // But prevent it from increasing damage
10822 dex_dodge = std::max( 0.0f, dex_dodge );
10823 // 100% damage at 0, 75% at 10, 50% at 20 and so on
10824 ret *= ( 100.0f - ( dex_dodge * 4.0f ) ) / 100.0f;
10825
10826 if( has_trait( trait_PARKOUR ) ) {
10827 ret *= 2.0f / 3.0f;
10828 }
10829
10830 // TODO: Bonus for Judo, mutations. Penalty for heavy weight (including mutations)
10831 return std::max( 0.0f, ret );
10832}
static const trait_id trait_PARKOUR("PARKOUR")
bool has_effect_with_flag(const std::string &flag, body_part bp=num_bp) const
Check if creature has any effect with the given flag.
Definition: creature.cpp:1229

References bp_leg_l, bp_leg_r, bp_torso, dex_cur, encumb(), get_skill_level(), Creature::has_effect_with_flag(), has_trait(), cata::hash64_detail::ret, skill_dodge, and trait_PARKOUR.

Referenced by impact(), and iexamine::ledge().

◆ feed_furnace_with()

bool Character::feed_furnace_with ( item it)

Recharge CBMs whenever possible.

Returns
true when recharging was successful.

Definition at line 1294 of file consumption.cpp.

1295{
1296 if( !can_feed_furnace_with( it ) ) {
1297 return false;
1298 }
1299 if( it.is_favorite &&
1300 !g->u.query_yn( _( "Are you sure you want to eat your favorited %s?" ), it.tname() ) ) {
1301 return false;
1302 }
1303
1304 const int consumed_charges = std::min( it.charges, it.charges_per_volume( furnace_max_volume ) );
1306
1307 if( energy == 0 ) {
1309 _( "You digest your %s, but fail to acquire energy from it." ),
1310 _( "<npcname> digests their %s for energy, but fails to acquire energy from it." ),
1311 it.tname() );
1312 } else if( is_max_power() ) {
1314 _( "You digest your %s, but you're fully powered already, so the energy is wasted." ),
1315 _( "<npcname> digests a %s for energy, they're fully powered already, so the energy is wasted." ),
1316 it.tname() );
1317 } else {
1318 const int profitable_energy = std::min( energy,
1320 if( it.count_by_charges() ) {
1322 vgettext( "You digest %d %s and recharge %d point of energy.",
1323 "You digest %d %s and recharge %d points of energy.",
1324 profitable_energy
1325 ),
1326 vgettext( "<npcname> digests %d %s and recharges %d point of energy.",
1327 "<npcname> digests %d %s and recharges %d points of energy.",
1328 profitable_energy
1329 ), consumed_charges, it.tname(), profitable_energy
1330 );
1331 } else {
1333 vgettext( "You digest your %s and recharge %d point of energy.",
1334 "You digest your %s and recharge %d points of energy.",
1335 profitable_energy
1336 ),
1337 vgettext( "<npcname> digests a %s and recharges %d point of energy.",
1338 "<npcname> digests a %s and recharges %d points of energy.",
1339 profitable_energy
1340 ), it.tname(), profitable_energy
1341 );
1342 }
1343 mod_power_level( units::from_kilojoule( profitable_energy ) );
1344 }
1345
1346 it.charges -= consumed_charges;
1347 mod_moves( -250 );
1348
1349 return true;
1350}
int get_acquirable_energy(const item &it, rechargeable_cbm cbm) const
bool can_feed_furnace_with(const item &it) const
Determine character's capability of recharging their CBMs.
bool is_max_power() const
Definition: character.cpp:1942
bool is_favorite
Definition: item.h:2249
quantity< int, energy_in_joule_tag > energy
Definition: units_energy.h:16
const char * vgettext(const char *msgid, const char *msgid_plural, size_t n)

References _, Creature::add_msg_player_or_npc(), can_feed_furnace_with(), item::charges, item::charges_per_volume(), item::count_by_charges(), units::from_kilojoule(), furnace, furnace_max_volume, g, get_acquirable_energy(), get_max_power_level(), get_power_level(), item::is_favorite, is_max_power(), m_info, Creature::mod_moves(), mod_power_level(), item::tname(), units::to_kilojoule(), and vgettext().

Referenced by consume_item().

◆ find_remote_fuel()

itype_id Character::find_remote_fuel ( bool  look_only = false)

Find fuel used by remote powered bionic.

Definition at line 1399 of file bionics.cpp.

1400{
1401 itype_id remote_fuel;
1402 map &here = get_map();
1403
1404 const std::vector<item *> cables = items_with( []( const item & it ) {
1405 return it.active && it.has_flag( flag_CABLE_SPOOL );
1406 } );
1407
1408 for( const item *cable : cables ) {
1409
1410 const std::optional<tripoint> target = cable->get_cable_target( this, pos() );
1411 if( !target ) {
1412 if( here.is_outside( pos() ) && !is_night( calendar::turn ) &&
1413 cable->get_var( "state" ) == "solar_pack_link" ) {
1414 if( !look_only ) {
1415 set_value( "sunlight", "1" );
1416 }
1417 remote_fuel = fuel_type_sun_light;
1418 }
1419
1420 if( cable->get_var( "state" ) == "UPS_link" ) {
1421 static const item_filter used_ups = [&]( const item & itm ) {
1422 return itm.get_var( "cable" ) == "plugged_in";
1423 };
1424 if( !look_only ) {
1425 if( has_charges( itype_UPS_off, 1, used_ups ) ) {
1427 units::to_kilojoule( max_power_level ), used_ups ) ) );
1428 } else if( has_charges( itype_adv_UPS_off, 1, used_ups ) ) {
1430 units::to_kilojoule( max_power_level ), used_ups ) ) );
1431 } else {
1432 set_value( "rem_battery", std::to_string( 0 ) );
1433 }
1434 }
1435 remote_fuel = fuel_type_battery;
1436 }
1437 continue;
1438 }
1439 const optional_vpart_position vp = here.veh_at( *target );
1440 if( !vp ) {
1441 continue;
1442 }
1443 if( !look_only ) {
1444 set_value( "rem_battery", std::to_string( vp->vehicle().fuel_left( fuel_type_battery,
1445 true ) ) );
1446 }
1447 remote_fuel = fuel_type_battery;
1448 }
1449
1450 return remote_fuel;
1451}
static const itype_id fuel_type_battery("battery")
bool is_night(const time_point &p)
Returns true if it's currently night time - after dusk and before dawn.
Definition: calendar.cpp:137
units::energy max_power_level
Definition: character.h:2247
int charges_of(const itype_id &what, int limit=INT_MAX, const std::function< bool(const item &)> &filter=return_true< item >, std::function< void(int)> visitor=nullptr) const
Count maximum available charges from this instance and any contained items.
Definition: visitable.cpp:947

References item::active, visitable< Character >::charges_of(), flag_CABLE_SPOOL(), fuel_type_battery, fuel_type_sun_light, get_map(), has_charges(), item::has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), is_night(), visitable< Character >::items_with(), itype_adv_UPS_off, itype_UPS_off, max_power_level, pos(), Creature::set_value(), units::to_kilojoule(), to_string(), and calendar::turn.

Referenced by burn_fuel(), iuse::cable_attach(), draw_bionics_titlebar(), and process_bionic().

◆ flag_encumbrance()

void Character::flag_encumbrance ( )

Flag encumbrance for updating.

Definition at line 1763 of file character.cpp.

1764{
1765 check_encumbrance = true;
1766}

References check_encumbrance.

Referenced by monexamine::attach_bag_to(), item::on_drop(), item::on_pickup(), and item::on_wield().

◆ floor_bedding_warmth()

int Character::floor_bedding_warmth ( const tripoint pos)
static

Warmth from terrain, furniture, vehicle furniture and traps.

Can be negative.

Definition at line 9475 of file character.cpp.

9476{
9477 map &here = get_map();
9478 const trap &trap_at_pos = here.tr_at( pos );
9479 const ter_id ter_at_pos = here.ter( pos );
9480 const furn_id furn_at_pos = here.furn( pos );
9481 int floor_bedding_warmth = 0;
9482
9483 const optional_vpart_position vp = here.veh_at( pos );
9484 const std::optional<vpart_reference> boardable = vp.part_with_feature( "BOARDABLE", true );
9485 // Search the floor for bedding
9486 if( furn_at_pos != f_null ) {
9488 } else if( !trap_at_pos.is_null() ) {
9490 } else if( boardable ) {
9491 floor_bedding_warmth += boardable->info().floor_bedding_warmth;
9492 } else if( ter_at_pos == t_improvised_shelter ) {
9493 floor_bedding_warmth -= 500;
9494 } else {
9495 floor_bedding_warmth -= 2000;
9496 }
9497
9498 return floor_bedding_warmth;
9499}
static int floor_bedding_warmth(const tripoint &pos)
Warmth from terrain, furniture, vehicle furniture and traps.
Definition: character.cpp:9475
const T & obj() const
Definition: ammo_effect.cpp:26
std::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2483
ter_id t_improvised_shelter
Definition: mapdata.cpp:719
int floor_bedding_warmth
Definition: mapdata.h:512
Definition: trap.h:86
int floor_bedding_warmth
Definition: trap.h:120

References f_null, floor_bedding_warmth(), furn_t::floor_bedding_warmth, trap::floor_bedding_warmth, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), trap::is_null(), int_id< T >::obj(), optional_vpart_position::part_with_feature(), pos(), and t_improvised_shelter.

Referenced by floor_bedding_warmth(), and floor_warmth().

◆ floor_item_warmth()

int Character::floor_item_warmth ( const tripoint pos)
static

Warmth from clothing on the floor.

Definition at line 9501 of file character.cpp.

9502{
9503 int item_warmth = 0;
9504
9505 const auto warm = [&item_warmth]( const auto & stack ) {
9506 for( const item &elem : stack ) {
9507 if( !elem.is_armor() ) {
9508 continue;
9509 }
9510 // Items that are big enough and covers the torso are used to keep warm.
9511 // Smaller items don't do as good a job
9512 if( elem.volume() > 250_ml &&
9513 ( elem.covers( bp_torso ) || elem.covers( bp_leg_l ) ||
9514 elem.covers( bp_leg_r ) ) ) {
9515 item_warmth += 60 * elem.get_warmth() * elem.volume() / 2500_ml;
9516 }
9517 }
9518 };
9519
9520 map &here = get_map();
9521 if( !!here.veh_at( pos ) ) {
9522 if( const std::optional<vpart_reference> vp = here.veh_at( pos ).part_with_feature( VPFLAG_CARGO,
9523 false ) ) {
9524 vehicle *const veh = &vp->vehicle();
9525 const int cargo = vp->part_index();
9526 vehicle_stack vehicle_items = veh->get_items( cargo );
9527 warm( vehicle_items );
9528 }
9529 return item_warmth;
9530 }
9531 map_stack floor_items = here.i_at( pos );
9532 warm( floor_items );
9533 return item_warmth;
9534}
A vehicle as a whole with all its components.
Definition: vehicle.h:383
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:253
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5491
@ VPFLAG_CARGO
Definition: veh_type.h:62

References bp_leg_l, bp_leg_r, bp_torso, vehicle::get_items(), get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), pos(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by floor_warmth().

◆ floor_warmth()

int Character::floor_warmth ( const tripoint pos) const

Final warmth from the floor.

Definition at line 9536 of file character.cpp.

9537{
9538 const int item_warmth = floor_item_warmth( pos );
9539 int bedding_warmth = floor_bedding_warmth( pos );
9540
9541 // If the PC has fur, etc, that will apply too
9542 int floor_mut_warmth = bodytemp_modifier_traits_floor();
9543 // DOWN does not provide floor insulation, though.
9544 // Better-than-light fur or being in one's shell does.
9545 if( ( !( has_trait( trait_DOWN ) ) ) && ( floor_mut_warmth >= 200 ) ) {
9546 bedding_warmth = std::max( 0, bedding_warmth );
9547 }
9548 return ( item_warmth + bedding_warmth + floor_mut_warmth );
9549}
static const trait_id trait_DOWN("DOWN")
static int floor_item_warmth(const tripoint &pos)
Warmth from clothing on the floor.
Definition: character.cpp:9501
int bodytemp_modifier_traits_floor() const
Correction factor of the body temperature due to traits and mutations for player lying on the floor.
Definition: character.cpp:9560

References bodytemp_modifier_traits_floor(), floor_bedding_warmth(), floor_item_warmth(), has_trait(), pos(), and trait_DOWN.

Referenced by update_bodytemp().

◆ footwear_factor()

double Character::footwear_factor ( ) const

Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.

Definition at line 8942 of file character.cpp.

8943{
8944 double ret = 0;
8945 if( wearing_something_on( bodypart_id( "foot_l" ) ) ) {
8946 ret += .5;
8947 }
8948 if( wearing_something_on( bodypart_id( "foot_r" ) ) ) {
8949 ret += .5;
8950 }
8951 return ret;
8952}

References cata::hash64_detail::ret, and wearing_something_on().

Referenced by is_immune_effect(), game::knockback(), rooted(), run_cost(), and game::walk_move().

◆ forced_dismount()

void Character::forced_dismount ( )

Definition at line 1087 of file character.cpp.

1088{
1090 bool mech = false;
1091 if( mounted_creature ) {
1092 auto mon = mounted_creature.get();
1093 if( mon->has_flag( MF_RIDEABLE_MECH ) && !mon->type->mech_weapon.is_empty() ) {
1094 mech = true;
1096 }
1097 mon->mounted_player_id = character_id();
1098 mon->remove_effect( effect_ridden );
1099 mon->add_effect( effect_ai_waiting, 5_turns );
1100 mounted_creature = nullptr;
1101 mon->mounted_player = nullptr;
1102 }
1103 std::vector<tripoint> valid;
1104 for( const tripoint &jk : get_map().points_in_radius( pos(), 1 ) ) {
1105 if( g->is_empty( jk ) ) {
1106 valid.push_back( jk );
1107 }
1108 }
1109 if( !valid.empty() ) {
1110 setpos( random_entry( valid ) );
1111 if( mech ) {
1112 add_msg_player_or_npc( m_bad, _( "You are ejected from your mech!" ),
1113 _( "<npcname> is ejected from their mech!" ) );
1114 } else {
1115 add_msg_player_or_npc( m_bad, _( "You fall off your mount!" ),
1116 _( "<npcname> falls off their mount!" ) );
1117 }
1118 const int dodge = get_dodge();
1119 const int damage = std::max( 0, rng( 1, 20 ) - rng( dodge, dodge * 2 ) );
1120 bodypart_id hit( "num_bp" );
1121 switch( rng( 1, 10 ) ) {
1122 case 1:
1123 if( one_in( 2 ) ) {
1124 hit = bodypart_id( "foot_l" );
1125 } else {
1126 hit = bodypart_id( "foot_r" );
1127 }
1128 break;
1129 case 2:
1130 case 3:
1131 case 4:
1132 if( one_in( 2 ) ) {
1133 hit = bodypart_id( "leg_l" );
1134 } else {
1135 hit = bodypart_id( "leg_r" );
1136 }
1137 break;
1138 case 5:
1139 case 6:
1140 case 7:
1141 if( one_in( 2 ) ) {
1142 hit = bodypart_id( "arm_l" );
1143 } else {
1144 hit = bodypart_id( "arm_r" );
1145 }
1146 break;
1147 case 8:
1148 case 9:
1149 hit = bodypart_id( "torso" );
1150 break;
1151 case 10:
1152 hit = bodypart_id( "head" );
1153 break;
1154 }
1155 if( damage > 0 ) {
1156 add_msg_if_player( m_bad, _( "You hurt yourself!" ) );
1157 deal_damage( nullptr, hit, damage_instance( DT_BASH, damage ) );
1158 if( is_avatar() ) {
1159 g->memorial().add(
1160 pgettext( "memorial_male", "Fell off a mount." ),
1161 pgettext( "memorial_female", "Fell off a mount." ) );
1162 }
1164 }
1165 add_effect( effect_downed, 5_turns, num_bp );
1166 } else {
1167 add_msg( m_debug, "Forced_dismount could not find a square to deposit player" );
1168 }
1169 if( is_avatar() ) {
1170 if( g->u.get_grab_type() != OBJECT_NONE ) {
1171 add_msg( m_warning, _( "You let go of the grabbed object." ) );
1172 g->u.grab( OBJECT_NONE );
1173 }
1175 if( g->u.is_auto_moving() || g->u.has_destination() || g->u.has_destination_activity() ) {
1176 g->u.clear_destination();
1177 }
1178 g->update_map( g->u );
1179 }
1180 if( activity ) {
1182 }
1183 moves -= 150;
1184}
static const efftype_id effect_downed("downed")
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8466
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1899

References character_id, effect_ai_waiting, effect_ridden, effect_riding, g, get_map(), MF_RIDEABLE_MECH, mounted_creature, points_in_radius(), pos(), primary_weapon(), random_entry(), Creature::remove_effect(), visitable< Character >::remove_item(), and setpos().

Referenced by Creature::add_effect(), check_mount_is_spooked(), monster::die(), and monster::setpos().

◆ fuel_bionic_with()

bool Character::fuel_bionic_with ( item it)

Definition at line 1352 of file consumption.cpp.

1353{
1354 if( !can_fuel_bionic_with( it ) ) {
1355 return false;
1356 }
1357
1359 const std::string str_loaded = get_value( it.typeId().str() );
1360
1361 const int fuel_multiplier = get_bionic_state( bio ).info().fuel_multiplier;
1362
1363 int loadable = std::min( it.charges * fuel_multiplier, get_fuel_capacity( it.typeId() ) );
1364 int loaded = 0;
1365
1366 if( !str_loaded.empty() ) {
1367 loaded = std::stoi( str_loaded );
1368 }
1369
1370 const std::string new_charge = std::to_string( loadable + loaded );
1371
1372 loadable = std::ceil( loadable / fuel_multiplier );
1373 it.charges -= loadable;
1374 // Type and amount of fuel
1375 set_value( it.typeId().str(), new_charge );
1378 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1379 vgettext( "You load %1$i charge of %2$s in your %3$s.",
1380 "You load %1$i charges of %2$s in your %3$s.", loadable ),
1381 //~ %1$i: charge number, %2$s: item name, %3$s: bionics name
1382 vgettext( "<npcname> load %1$i charge of %2$s in their %3$s.",
1383 "<npcname> load %1$i charges of %2$s in their %3$s.", loadable ), loadable, it.tname(), bio->name );
1384 mod_moves( -250 );
1385 return true;
1386}
bionic_id get_most_efficient_bionic(const std::vector< bionic_id > &bids) const
Return bionic_id of bionic of most fuel efficient bionic.
Definition: character.cpp:1892
bool can_fuel_bionic_with(const item &it) const
Returns true if the character can fuel a bionic with the item.
Definition: character.cpp:1850
int get_fuel_capacity(const itype_id &fuel) const
Return available space to store specified fuel.
Definition: character.cpp:2035
int fuel_multiplier
Multiplies the amount of fuel when loading into the bionic storage.
Definition: bionics.h:73

References Creature::add_msg_player_or_npc(), can_fuel_bionic_with(), item::charges, bionic_data::fuel_multiplier, get_bionic_fueled_with(), get_bionic_state(), get_fuel_capacity(), get_most_efficient_bionic(), Creature::get_value(), bionic::info(), m_info, Creature::mod_moves(), bionic_data::name, Creature::set_value(), string_id< T >::str(), item::tname(), to_string(), item::typeId(), update_fuel_storage(), and vgettext().

Referenced by consume_item().

◆ fun_for()

std::pair< int, int > Character::fun_for ( const item comest) const

Handles the enjoyability value for a comestible.

First value is enjoyability, second is cap.

Definition at line 472 of file consumption.cpp.

473{
474 if( !comest.is_comestible() ) {
475 return std::pair<int, int>( 0, 0 );
476 }
477
478 // As float to avoid rounding too many times
479 float fun = comest.get_comestible_fun();
480 float fun_max;
481
482 // Lupines/Felines like dog/cat food. Won't skip the rotting check.
483 // This is specifically so that Lupines/Felines don't get the harsher
484 // morale penalties from rotting cat/dog food.
485 if( ( comest.has_flag( flag_LUPINE ) && has_trait( trait_THRESH_LUPINE ) ) ||
486 ( comest.has_flag( flag_FELINE ) && has_trait( trait_THRESH_FELINE ) ) ) {
487 if( fun < 0 ) {
488 fun = -fun / 2;
489 }
490 }
491
492 const float relative_rot = comest.get_relative_rot();
493
494 if( relative_rot > 1.0f && !has_trait( trait_SAPROPHAGE ) && !has_trait( trait_SAPROVORE ) ) {
495 // Rotten food should be pretty disgusting.
496 // Baseline minumum is the same as eating raw meat as a normal human being.
497 fun = std::min( fun - 5, -10.0f );
498 fun_max = fun * 6;
499 } else {
500 // Food is less enjoyable when eaten too often.
501 if( fun > 0 || comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
502 for( const consumption_event &event : consumption_history->elems ) {
503 if( event.time > calendar::turn - 2_days && event.type_id == comest.typeId() &&
504 event.component_hash == comest.make_component_hash() ) {
505 fun -= comest.get_comestible()->monotony_penalty;
506 // This effect can't drop fun below 0, unless the food has the right flag.
507 // 0 is the lowest we'll go, no need to keep looping.
508 if( fun <= 0 && !comest.has_flag( flag_NEGATIVE_MONOTONY_OK ) ) {
509 fun = 0;
510 break;
511 }
512 }
513 }
514 }
515
516 fun_max = fun < 0 ? fun * 6 : fun * 3;
517
518 // I'd assume since gourmands are just big eaters they still can't stand rotten food.
519 if( has_trait( trait_GOURMAND ) ) {
520 if( fun < -1 ) {
521 fun_max = fun;
522 fun /= 2;
523 } else if( fun > 0 ) {
524 fun_max *= 3;
525 fun = fun * 3 / 2;
526 }
527 }
528 }
529
530 return { static_cast< int >( fun ), static_cast< int >( fun_max ) };
531}
uint64_t make_component_hash() const
Creates a hash from the itype_ids of this item's components.
Definition: item.cpp:8919
int get_comestible_fun() const
Definition: item.cpp:5509
static const std::string flag_NEGATIVE_MONOTONY_OK("NEGATIVE_MONOTONY_OK")
time_point time
Definition: consumption.h:15
uint64_t component_hash
Definition: consumption.h:17
itype_id type_id
Definition: consumption.h:16

References consumption_event::component_hash, consumption_history, flag_FELINE(), flag_LUPINE(), flag_NEGATIVE_MONOTONY_OK(), item::get_comestible(), item::get_comestible_fun(), item::get_relative_rot(), item::has_flag(), has_trait(), item::is_comestible(), item::make_component_hash(), consumption_event::time, trait_GOURMAND, trait_SAPROPHAGE, trait_SAPROVORE, trait_THRESH_FELINE, trait_THRESH_LUPINE, calendar::turn, consumption_event::type_id, and item::typeId().

Referenced by comestible_inventory_preset::comestible_inventory_preset(), find_auto_consume(), item::food_info(), and modify_morale().

◆ get_acquirable_energy() [1/2]

int Character::get_acquirable_energy ( const item it) const

Definition at line 1447 of file consumption.cpp.

1448{
1450}

References get_acquirable_energy(), and get_cbm_rechargeable_with().

◆ get_acquirable_energy() [2/2]

int Character::get_acquirable_energy ( const item it,
rechargeable_cbm  cbm 
) const

Definition at line 1401 of file consumption.cpp.

1402{
1403 switch( cbm ) {
1405 break;
1406
1408 if( it.charges > 0 ) {
1409 const auto iter = plut_charges.find( it.typeId() );
1410 return iter != plut_charges.end() ? it.charges * iter->second : 0;
1411 }
1412
1413 break;
1414
1416 units::volume consumed_vol = it.volume();
1417 units::mass consumed_mass = it.weight();
1419 const double n_stacks = static_cast<double>( it.charges_per_volume( furnace_max_volume ) ) /
1420 it.type->stack_size;
1421 consumed_vol = it.type->volume * n_stacks;
1422 // it.type->weight is in 10g units?
1423 consumed_mass = it.type->weight * 10 * n_stacks;
1424 }
1425 int amount = ( consumed_vol / 250_ml + consumed_mass / 1_gram ) / 9;
1426
1427 // TODO: JSONize.
1428 if( it.made_of( material_id( "leather" ) ) ) {
1429 amount /= 4;
1430 }
1431 if( it.made_of( material_id( "wood" ) ) ) {
1432 amount /= 2;
1433 }
1434
1435 return amount;
1436 }
1439 const int to_consume = std::min( it.charges, bid->fuel_capacity );
1440 const int to_charge = static_cast<int>( it.fuel_energy() * to_consume * bid->fuel_efficiency );
1441 return to_charge;
1442 }
1443
1444 return 0;
1445}
const std::map< itype_id, int > plut_charges
int fuel_capacity
How much fuel this bionic can hold.
Definition: bionics.h:69
units::mass weight
Weight of item ( or each stack member )
Definition: itype.h:936
int stack_size
Number of items per above volume for count_by_charges items.
Definition: itype.h:953
units::volume volume
Space occupied by items of this type CAUTION: value given is for a default-sized stack.
Definition: itype.h:945

References item::charges, item::charges_per_volume(), item::count_by_charges(), bionic_data::fuel_capacity, bionic_data::fuel_efficiency, item::fuel_energy(), furnace, furnace_max_volume, get_bionic_fueled_with(), get_most_efficient_bionic(), item::made_of(), none, other, plut_charges, reactor, itype::stack_size, item::type, item::typeId(), item::volume(), itype::volume, item::weight(), and itype::weight.

Referenced by feed_furnace_with(), and get_acquirable_energy().

◆ get_all_armor_type()

std::map< bodypart_id, int > Character::get_all_armor_type ( damage_type  dt,
const std::map< bodypart_id, std::vector< const item * > > &  clothing_map 
) const

Definition at line 6924 of file character.cpp.

6926{
6927 std::map<bodypart_id, int> ret;
6928 for( const bodypart_id &bp : get_all_body_parts() ) {
6929 ret.emplace( bp, 0 );
6930 }
6931
6932 for( std::pair<const bodypart_id, int> &per_bp : ret ) {
6933 const bodypart_id &bp = per_bp.first;
6934 switch( dt ) {
6935 case DT_TRUE:
6936 case DT_BIOLOGICAL:
6937 // Characters cannot resist this
6938 return ret;
6939 /* BASH, CUT, STAB, and BULLET don't benefit from the clothing_map optimization */
6940 // TODO: Fix that
6941 case DT_BASH:
6942 per_bp.second += get_armor_bash( bp );
6943 break;
6944 case DT_CUT:
6945 per_bp.second += get_armor_cut( bp );
6946 break;
6947 case DT_STAB:
6948 per_bp.second += get_armor_cut( bp ) * 0.8f;
6949 break;
6950 case DT_BULLET:
6951 per_bp.second += get_armor_bullet( bp );
6952 break;
6953 case DT_ACID:
6954 case DT_HEAT:
6955 case DT_COLD:
6956 case DT_ELECTRIC: {
6957 for( const item *it : clothing_map.at( bp ) ) {
6958 per_bp.second += it->damage_resist( dt );
6959 }
6960
6961 per_bp.second += mutation_armor( bp, dt );
6962 break;
6963 }
6964 case DT_NULL:
6965 case NUM_DT:
6966 debugmsg( "Invalid damage type: %d", dt );
6967 return ret;
6968 }
6969 }
6970
6971 return ret;
6972}
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6875
int get_armor_bullet(bodypart_id bp) const override
Returns overall bullet resistance for the body_part.
Definition: character.cpp:6880
int get_armor_bash(bodypart_id bp) const override
Returns overall bashing resistance for the body_part.
Definition: character.cpp:6870
resistances mutation_armor(bodypart_id bp) const
Returns resistances on a body part provided by mutations.
Definition: character.cpp:6434
@ DT_TRUE
Definition: damage.h:22
@ DT_NULL
Definition: damage.h:21
@ NUM_DT
Definition: damage.h:32
@ DT_BIOLOGICAL
Definition: damage.h:23

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, Creature::get_all_body_parts(), get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, and cata::hash64_detail::ret.

Referenced by get_armor_fire().

◆ get_all_skills()

const SkillLevelMap & Character::get_all_skills ( ) const

Definition at line 3335 of file character.cpp.

3336{
3337 return *_skills;
3338}

References _skills.

Referenced by player::has_recipe_requirements(), lighting_crafting_speed_multiplier(), set_skills(), and memorial_logger::write().

◆ get_armor_acid()

int Character::get_armor_acid ( bodypart_id  bp) const

Returns overall acid resistance for the body part.

Definition at line 7055 of file character.cpp.

7056{
7057 return get_armor_type( DT_ACID, bp );
7058}
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6886

References DT_ACID, and get_armor_type().

◆ get_armor_bash()

int Character::get_armor_bash ( bodypart_id  bp) const
overridevirtual

Returns overall bashing resistance for the body_part.

Reimplemented from Creature.

Definition at line 6870 of file character.cpp.

6871{
6873}
int get_armor_bash_base(bodypart_id bp) const override
Returns bashing resistance from the creature and armor only.
Definition: character.cpp:6974
int armor_bash_bonus
Definition: creature.h:832

References Creature::armor_bash_bonus, and get_armor_bash_base().

Referenced by get_all_armor_type(), get_armor_type(), game::get_dangerous_tile(), and game::place_player().

◆ get_armor_bash_base()

int Character::get_armor_bash_base ( bodypart_id  bp) const
overridevirtual

Returns bashing resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6974 of file character.cpp.

6975{
6976 int ret = 0;
6977 for( auto &i : worn ) {
6978 if( i.covers( bp->token ) ) {
6979 ret += i.bash_resist();
6980 }
6981 }
6982 for( const bionic_id &bid : get_bionics() ) {
6983 const auto bash_prot = bid->bash_protec.find( bp.id() );
6984 if( bash_prot != bid->bash_protec.end() ) {
6985 ret += bash_prot->second;
6986 }
6987 }
6988
6989 ret += mutation_armor( bp, DT_BASH );
6990 return ret;
6991}

References DT_BASH, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bash().

◆ get_armor_bullet()

int Character::get_armor_bullet ( bodypart_id  bp) const
overridevirtual

Returns overall bullet resistance for the body_part.

Reimplemented from Creature.

Definition at line 6880 of file character.cpp.

6881{
6883}
int get_armor_bullet_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:7012
int armor_bullet_bonus
Definition: creature.h:834

References Creature::armor_bullet_bonus, and get_armor_bullet_base().

Referenced by get_all_armor_type(), and get_armor_type().

◆ get_armor_bullet_base()

int Character::get_armor_bullet_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 7012 of file character.cpp.

7013{
7014 int ret = 0;
7015 for( auto &i : worn ) {
7016 if( i.covers( bp->token ) ) {
7017 ret += i.bullet_resist();
7018 }
7019 }
7020
7021 for( const bionic_id &bid : get_bionics() ) {
7022 const auto bullet_prot = bid->bullet_protec.find( bp.id() );
7023 if( bullet_prot != bid->bullet_protec.end() ) {
7024 ret += bullet_prot->second;
7025 }
7026 }
7027
7028 ret += mutation_armor( bp, DT_BULLET );
7029 return ret;
7030}

References DT_BULLET, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_bullet().

◆ get_armor_cut()

int Character::get_armor_cut ( bodypart_id  bp) const
overridevirtual

Returns overall cutting resistance for the body_part.

Reimplemented from Creature.

Definition at line 6875 of file character.cpp.

6876{
6877 return get_armor_cut_base( bp ) + armor_cut_bonus;
6878}
int get_armor_cut_base(bodypart_id bp) const override
Returns cutting resistance from the creature and armor only.
Definition: character.cpp:6993
int armor_cut_bonus
Definition: creature.h:833

References Creature::armor_cut_bonus, and get_armor_cut_base().

Referenced by get_all_armor_type(), get_armor_type(), and map::player_in_field().

◆ get_armor_cut_base()

int Character::get_armor_cut_base ( bodypart_id  bp) const
overridevirtual

Returns cutting resistance from the creature and armor only.

Reimplemented from Creature.

Definition at line 6993 of file character.cpp.

6994{
6995 int ret = 0;
6996 for( auto &i : worn ) {
6997 if( i.covers( bp->token ) ) {
6998 ret += i.cut_resist();
6999 }
7000 }
7001 for( const bionic_id &bid : get_bionics() ) {
7002 const auto cut_prot = bid->cut_protec.find( bp.id() );
7003 if( cut_prot != bid->cut_protec.end() ) {
7004 ret += cut_prot->second;
7005 }
7006 }
7007
7008 ret += mutation_armor( bp, DT_CUT );
7009 return ret;
7010}

References DT_CUT, get_bionics(), int_id< T >::id(), mutation_armor(), cata::hash64_detail::ret, and worn.

Referenced by get_armor_cut().

◆ get_armor_fire()

std::map< bodypart_id, int > Character::get_armor_fire ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns overall fire resistance.

Definition at line 8257 of file character.cpp.

8259{
8260 return get_all_armor_type( DT_HEAT, clothing_map );
8261}
std::map< bodypart_id, int > get_all_armor_type(damage_type dt, const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Definition: character.cpp:6924

References DT_HEAT, and get_all_armor_type().

Referenced by update_bodytemp().

◆ get_armor_type()

int Character::get_armor_type ( damage_type  dt,
bodypart_id  bp 
) const
overridevirtual

Returns overall resistance to given type on the bod part.

Implements Creature.

Definition at line 6886 of file character.cpp.

6887{
6888 switch( dt ) {
6889 case DT_TRUE:
6890 case DT_BIOLOGICAL:
6891 return 0;
6892 case DT_BASH:
6893 return get_armor_bash( bp );
6894 case DT_CUT:
6895 return get_armor_cut( bp );
6896 case DT_STAB:
6897 return get_armor_cut( bp ) * 0.8f;
6898 case DT_BULLET:
6899 return get_armor_bullet( bp );
6900 case DT_ACID:
6901 case DT_HEAT:
6902 case DT_COLD:
6903 case DT_ELECTRIC: {
6904 int ret = 0;
6905 for( auto &i : worn ) {
6906 if( i.covers( bp->token ) ) {
6907 ret += i.damage_resist( dt );
6908 }
6909 }
6910
6911 ret += mutation_armor( bp, dt );
6912 return ret;
6913 }
6914 case DT_NULL:
6915 case NUM_DT:
6916 // Let it error below
6917 break;
6918 }
6919
6920 debugmsg( "Invalid damage type: %d", dt );
6921 return 0;
6922}

References debugmsg, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, get_armor_bash(), get_armor_bullet(), get_armor_cut(), mutation_armor(), NUM_DT, cata::hash64_detail::ret, and worn.

Referenced by map::burn_body_part(), get_armor_acid(), and is_immune_field().

◆ get_auto_move_route()

std::vector< tripoint > & Character::get_auto_move_route ( )

Definition at line 10539 of file character.cpp.

10540{
10541 return auto_move_route;
10542}

References auto_move_route.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), npc::move(), and npc::move_to().

◆ get_base_traits()

std::vector< trait_id > Character::get_base_traits ( ) const

Get the idents of all base traits.

Definition at line 2855 of file newcharacter.cpp.

2856{
2857 return std::vector<trait_id>( my_traits.begin(), my_traits.end() );
2858}

References my_traits.

Referenced by avatar::create(), and set_description().

◆ get_bionic_fueled_with()

std::vector< bionic_id > Character::get_bionic_fueled_with ( const item it) const

Return bionic_id of bionics able to use it as fuel.

Definition at line 1866 of file character.cpp.

1867{
1868 std::vector<bionic_id> bionics;
1869
1870 for( const bionic_id &bid : get_bionics() ) {
1871 for( const itype_id &fuel : bid->fuel_opts ) {
1872 if( fuel == it.typeId() ) {
1873 bionics.emplace_back( bid );
1874 }
1875 }
1876 }
1877
1878 return bionics;
1879}

References get_bionics(), and item::typeId().

Referenced by burn_move_stamina(), fuel_bionic_with(), get_acquirable_energy(), game::on_move_effects(), reset_remote_fuel(), and update_fuel_storage().

◆ get_bionic_state()

bionic & Character::get_bionic_state ( const bionic_id id)

Get state of bionic with given id.

Definition at line 1804 of file character.cpp.

1805{
1806 for( bionic &b : *my_bionics ) {
1807 if( id == b.id ) {
1808 return b;
1809 }
1810 }
1811 debugmsg( "tried to get state of non-existent bionic with id \"%s\"", id );
1812 std::abort();
1813}

References b, debugmsg, and my_bionics.

Referenced by absorb_hit(), npc::activate_bionic_by_id(), npc::check_or_reload_cbm(), npc::deactivate_bionic_by_id(), fuel_bionic_with(), suffer_from_radiation(), and npc::use_bionic_by_id().

◆ get_bionics()

◆ get_cbm_rechargeable_with()

rechargeable_cbm Character::get_cbm_rechargeable_with ( const item it) const

Definition at line 1388 of file consumption.cpp.

1389{
1390 if( can_feed_furnace_with( it ) ) {
1392 }
1393
1394 if( can_fuel_bionic_with( it ) ) {
1396 }
1397
1399}

References can_feed_furnace_with(), can_fuel_bionic_with(), furnace, none, and other.

Referenced by can_consume_for_bionic(), and get_acquirable_energy().

◆ get_check_encumbrance()

bool Character::get_check_encumbrance ( ) const
inline

Definition at line 2018 of file character.h.

2018 {
2019 return check_encumbrance;
2020 }

References check_encumbrance.

Referenced by process_items().

◆ get_consumable_from()

item & Character::get_consumable_from ( item it) const

Returns a reference to the item itself (if it's consumable), the first of its contents (if it's consumable) or null item otherwise.

WARNING: consumable does not necessarily guarantee the comestible type.

Definition at line 1477 of file consumption.cpp.

1478{
1479 if( !it.is_container_empty() && can_consume_as_is( it.contents.front() ) ) {
1480 return it.contents.front();
1481 } else if( can_consume_as_is( it ) ) {
1482 return it;
1483 }
1484
1485 static item null_comestible;
1486 // Since it's not const.
1487 null_comestible = item();
1488 return null_comestible;
1489}

References can_consume_as_is(), item::contents, item_contents::front(), and item::is_container_empty().

Referenced by consume_item(), and find_auto_consume().

◆ get_dependent_worn_items()

std::list< item * > Character::get_dependent_worn_items ( const item it) const

Returns all items that must be taken off before taking off this item.

Definition at line 2426 of file character.cpp.

2427{
2428 std::list<item *> dependent;
2429 // Adds dependent worn items recursively
2430 const std::function<void( const item &it )> add_dependent = [&]( const item & it ) {
2431 for( const item &wit : worn ) {
2432 if( &wit == &it || !wit.is_worn_only_with( it ) ) {
2433 continue;
2434 }
2435 const auto iter = std::find_if( dependent.begin(), dependent.end(),
2436 [&wit]( const item * dit ) {
2437 return &wit == dit;
2438 } );
2439 if( iter == dependent.end() ) { // Not in the list yet
2440 add_dependent( wit );
2441 dependent.push_back( const_cast<item *>( & wit ) );
2442 }
2443 }
2444 };
2445
2446 if( is_worn( it ) ) {
2447 add_dependent( it );
2448 }
2449
2450 return dependent;
2451}

References is_worn(), item::is_worn_only_with(), and worn.

Referenced by can_takeoff(), and pickup::reorder_for_dropping().

◆ get_destination_activity()

player_activity Character::get_destination_activity ( ) const

Definition at line 963 of file character.cpp.

964{
966}

References destination_activity.

Referenced by has_destination_activity(), has_distant_destination(), and start_destination_activity().

◆ get_dex()

◆ get_dex_base()

int Character::get_dex_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4110 of file character.cpp.

4111{
4112 return dex_max;
4113}

References dex_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_dex(), and avatar::get_dex_base().

◆ get_dex_bonus()

int Character::get_dex_bonus ( ) const
virtual

Definition at line 4127 of file character.cpp.

4128{
4129 return dex_bonus;
4130}

References dex_bonus.

Referenced by reset_stats().

◆ get_dodge()

float Character::get_dodge ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 866 of file melee.cpp.

867{
868 //If we're asleep or busy we can't dodge
870 return 0.0f;
871 }
872
873 float ret = Creature::get_dodge();
874 // Chop in half if we are unable to move
877 ret /= 2;
878 }
879
880 if( has_effect( effect_grabbed ) ) {
881 int zed_number = 0;
882 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
883 const monster *const mon = g->critter_at<monster>( dest );
884 if( mon && mon->has_effect( effect_grabbing ) ) {
885 zed_number++;
886 }
887 }
888 ret *= 1.0f - ( 0.25f * zed_number );
889 }
890
891 if( worn_with_flag( "ROLLER_INLINE" ) ||
892 worn_with_flag( "ROLLER_QUAD" ) ||
893 worn_with_flag( "ROLLER_ONE" ) ) {
894 ret /= has_trait( trait_PROF_SKATER ) ? 2 : 5;
895 }
896
898 ret /= 4;
899 }
900
901 // Each dodge after the first subtracts equivalent of 2 points of dodge skill
902 if( dodges_left <= 0 ) {
903 ret += dodges_left * 2 - 2;
904 }
905
906 return std::max( 0.0f, ret );
907}
int dodges_left
Definition: character.h:569
virtual float get_dodge() const
Definition: creature.cpp:1550
static const efftype_id effect_lightsnare("lightsnare")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_bouldering("bouldering")
static const efftype_id effect_beartrap("beartrap")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_heavysnare("heavysnare")
static const trait_id trait_PROF_SKATER("PROF_SKATER")
auto dest(const elevator::tiles &elevator_here, const tripoint &sm_orig, int turns, int movez) -> elevator::tiles

References anonymous_namespace{iexamine_elevator.cpp}::elevator::dest(), dodges_left, effect_beartrap, effect_bouldering, effect_grabbed, effect_grabbing, effect_heavysnare, effect_lightsnare, effect_narcosis, g, Creature::get_dodge(), Creature::has_effect(), has_trait(), in_sleep_state(), pos(), cata::hash64_detail::ret, trait_PROF_SKATER, and worn_with_flag().

Referenced by npc::character_danger(), trapfunc::crossbow(), dodge_roll(), draw_skills_tab(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), mattack::science(), trapfunc::shotgun(), and game::update_stair_monsters().

◆ get_dodge_base()

float Character::get_dodge_base ( ) const
overridevirtual

Combat getters.

Dexterity increases dodge base Dodge increases dodge_base

Implements Creature.

Definition at line 5748 of file character.cpp.

5749{
5750 /** @EFFECT_DEX increases dodge base */
5751 /** @EFFECT_DODGE increases dodge_base */
5752 return get_dex() / 2.0f + get_skill_level( skill_dodge );
5753}

References get_dex(), get_skill_level(), and skill_dodge.

◆ get_effective_efficiency()

float Character::get_effective_efficiency ( bionic bio,
float  fuel_efficiency 
)

Applies modifier to fuel_efficiency and returns the resulting efficiency.

Definition at line 1516 of file bionics.cpp.

1517{
1518 const std::optional<float> &coverage_penalty = bio.info().coverage_power_gen_penalty;
1519 float effective_efficiency = fuel_efficiency;
1520 if( coverage_penalty ) {
1521 int coverage = 0;
1522 const std::map< bodypart_str_id, int > &occupied_bodyparts = bio.info().occupied_bodyparts;
1523 for( const std::pair< const bodypart_str_id, int > &elem : occupied_bodyparts ) {
1524 for( const item &i : worn ) {
1525 if( i.covers( elem.first->token ) && !i.has_flag( flag_ALLOWS_NATURAL_ATTACKS ) &&
1526 !i.has_flag( flag_SEMITANGIBLE ) &&
1527 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) ) {
1528 coverage += i.get_coverage();
1529 }
1530 }
1531 }
1532 effective_efficiency = fuel_efficiency * ( 1.0 - ( coverage / ( 100.0 *
1533 occupied_bodyparts.size() ) )
1534 * coverage_penalty.value() );
1535 }
1536 return effective_efficiency;
1537}
static const std::string flag_SEMITANGIBLE("SEMITANGIBLE")
static const std::string flag_ALLOWS_NATURAL_ATTACKS("ALLOWS_NATURAL_ATTACKS")
static const std::string flag_AURA("AURA")
static const std::string flag_PERSONAL("PERSONAL")
std::optional< float > coverage_power_gen_penalty
Fraction of coverage diminishing fuel_efficiency.
Definition: bionics.h:77

References bionic_data::coverage_power_gen_penalty, flag_ALLOWS_NATURAL_ATTACKS(), flag_AURA(), flag_PERSONAL(), flag_SEMITANGIBLE(), bionic::info(), bionic_data::occupied_bodyparts, and worn.

Referenced by burn_fuel(), and passive_power_gen().

◆ get_encumbrance() [1/2]

char_encumbrance_data Character::get_encumbrance ( ) const

Get encumbrance for all body parts.

Definition at line 3705 of file character.cpp.

3706{
3707 return *encumbrance_cache;
3708}

References encumbrance_cache.

Referenced by item::on_wear(), character_display::print_encumbrance(), and should_combine_bps().

◆ get_encumbrance() [2/2]

char_encumbrance_data Character::get_encumbrance ( const item new_item) const

Get encumbrance for all body parts as if new_item was also worn.

Definition at line 3710 of file character.cpp.

3711{
3712 return calc_encumbrance( new_item );
3713}

References calc_encumbrance().

◆ get_env_resist()

int Character::get_env_resist ( bodypart_id  bp) const
overridevirtual

Returns overall env_resist on a body_part.

Reimplemented from Creature.

Definition at line 7032 of file character.cpp.

7033{
7034 int ret = 0;
7035 for( auto &i : worn ) {
7036 // Head protection works on eyes too (e.g. baseball cap)
7037 if( i.covers( bp->token ) || ( bp == bodypart_id( "eyes" ) && i.covers( bp_head ) ) ) {
7038 ret += i.get_env_resist();
7039 }
7040 }
7041
7042 for( const bionic_id &bid : get_bionics() ) {
7043 const auto EP = bid->env_protec.find( bp.id() );
7044 if( ( !bid->activated || has_active_bionic( bid ) ) && EP != bid->env_protec.end() ) {
7045 ret += EP->second;
7046 }
7047 }
7048
7049 if( bp == bodypart_id( "eyes" ) && has_trait( trait_SEESLEEP ) ) {
7050 ret += 8;
7051 }
7052 return ret;
7053}
static const trait_id trait_SEESLEEP("SEESLEEP")

References bp_head, get_bionics(), has_active_bionic(), has_trait(), int_id< T >::id(), cata::hash64_detail::ret, trait_SEESLEEP, and worn.

Referenced by iexamine::flower_poppy(), is_immune_field(), and map::player_in_field().

◆ get_faction()

virtual faction * Character::get_faction ( ) const
inlinevirtual

Reimplemented in avatar, and npc.

Definition at line 368 of file character.h.

368 {
369 return nullptr;
370 }

Referenced by complete_craft(), npc::consume_food_from_camp(), basecamp::faction_display(), and npc::has_faction_relationship().

◆ get_fatigue()

◆ get_fatigue_description()

std::pair< std::string, nc_color > Character::get_fatigue_description ( ) const

Definition at line 4421 of file character.cpp.

4422{
4423 int fatigue = get_fatigue();
4424 std::string fatigue_string;
4425 nc_color fatigue_color = c_white;
4427 fatigue_color = c_red;
4428 fatigue_string = _( "Exhausted" );
4429 } else if( fatigue > fatigue_levels::dead_tired ) {
4430 fatigue_color = c_light_red;
4431 fatigue_string = _( "Dead Tired" );
4432 } else if( fatigue > fatigue_levels::tired ) {
4433 fatigue_color = c_yellow;
4434 fatigue_string = _( "Tired" );
4435 }
4436 return std::make_pair( fatigue_string, fatigue_color );
4437}

References _, c_light_red, c_red, c_white, c_yellow, dead_tired, exhausted, fatigue, get_fatigue(), and tired.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), spell::energy_cur_string(), npc::faction_display(), and get_consume_needs_hint().

◆ get_free_bionics_slots()

int Character::get_free_bionics_slots ( const bodypart_id bp) const

Definition at line 2575 of file bionics.cpp.

2576{
2578}
int get_total_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2570
int get_used_bionics_slots(const bodypart_id &bp) const
Definition: bionics.cpp:2542

References get_total_bionics_slots(), and get_used_bionics_slots().

Referenced by bionic_installation_issues(), and show_bionics_ui().

◆ get_fuel_available()

std::vector< itype_id > Character::get_fuel_available ( const bionic_id bio) const

Return list of available fuel for this bionic.

Definition at line 2014 of file character.cpp.

2015{
2016 std::vector<itype_id> stored_fuels;
2017 for( const itype_id &fuel : bio->fuel_opts ) {
2018 const item tmp_fuel( fuel );
2019 if( !get_value( fuel.str() ).empty() || tmp_fuel.has_flag( flag_PERPETUAL ) ) {
2020 stored_fuels.emplace_back( fuel );
2021 }
2022 }
2023 return stored_fuels;
2024}
static const std::string flag_PERPETUAL("PERPETUAL")

References flag_PERPETUAL(), bionic_data::fuel_opts, Creature::get_value(), item::has_flag(), and string_id< T >::str().

Referenced by burn_fuel(), draw_bionics_titlebar(), passive_power_gen(), process_bionic(), and npc::recharge_cbm().

◆ get_fuel_capacity()

int Character::get_fuel_capacity ( const itype_id fuel) const

Return available space to store specified fuel.

Definition at line 2035 of file character.cpp.

2036{
2037 int amount_stored = 0;
2038 if( !get_value( fuel.str() ).empty() ) {
2039 amount_stored = std::stoi( get_value( fuel.str() ) );
2040 }
2041 int capacity = 0;
2042 for( const bionic_id &bid : get_bionics() ) {
2043 for( const itype_id &fl : bid->fuel_opts ) {
2044 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2045 if( fl == fuel ) {
2046 capacity += bid->fuel_capacity;
2047 }
2048 }
2049 }
2050 }
2051 return capacity - amount_stored;
2052}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by fuel_bionic_with().

◆ get_fuel_type_available()

int Character::get_fuel_type_available ( const itype_id fuel) const

Return available space to store specified fuel.

Definition at line 2026 of file character.cpp.

2027{
2028 int amount_stored = 0;
2029 if( !get_value( fuel.str() ).empty() ) {
2030 amount_stored = std::stoi( get_value( fuel.str() ) );
2031 }
2032 return amount_stored;
2033}

References Creature::get_value(), and string_id< T >::str().

Referenced by suffer_from_radiation().

◆ get_fueled_bionics()

std::vector< bionic_id > Character::get_fueled_bionics ( ) const

Return bionic_id of fueled bionics.

Definition at line 1881 of file character.cpp.

1882{
1883 std::vector<bionic_id> bionics;
1884 for( const bionic_id &bid : get_bionics() ) {
1885 if( !bid->fuel_opts.empty() ) {
1886 bionics.emplace_back( bid );
1887 }
1888 }
1889 return bionics;
1890}

References get_bionics().

Referenced by npc::recharge_cbm(), and npc::wants_to_recharge_cbm().

◆ get_grammatical_genders()

std::vector< std::string > Character::get_grammatical_genders ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 6009 of file character.cpp.

6010{
6011 if( male ) {
6012 return { "m" };
6013 } else {
6014 return { "f" };
6015 }
6016}

References male.

Referenced by translate_gendered_line().

◆ get_healthy()

int Character::get_healthy ( ) const
virtual

Getters for health values exclusive to characters.

Definition at line 4166 of file character.cpp.

4167{
4168 return healthy;
4169}

References healthy.

Referenced by debug_menu::character_edit_menu(), eff_fun_fungus(), eff_fun_spores(), expose_to_disease(), hardcoded_effects(), healing_rate(), healing_rate_medicine(), print_health(), process_one_effect(), and update_health().

◆ get_healthy_mod()

int Character::get_healthy_mod ( ) const
virtual

Definition at line 4170 of file character.cpp.

4171{
4172 return healthy_mod;
4173}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), process_one_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ get_highest_category()

std::string Character::get_highest_category ( ) const

Returns the highest mutation category.

Returns the mutation category with the highest strength.

Definition at line 7847 of file character.cpp.

7848{
7849 int iLevel = 0;
7850 std::string sMaxCat;
7851
7852 for( const std::pair<const std::string, int> &elem : mutation_category_level ) {
7853 if( elem.second > iLevel ) {
7854 sMaxCat = elem.first;
7855 iLevel = elem.second;
7856 } else if( elem.second == iLevel ) {
7857 sMaxCat.clear(); // no category on ties
7858 }
7859 }
7860 return sMaxCat;
7861}
std::map< std::string, int > mutation_category_level
Definition: character.h:1779

References mutation_category_level.

Referenced by hardcoded_effects(), old_mutate(), map::player_in_field(), and test_crossing_threshold().

◆ get_hit_base()

float Character::get_hit_base ( ) const
overridevirtual
Dexterity increases hit base, slightly

Implements Creature.

Definition at line 5754 of file character.cpp.

5755{
5756 /** @EFFECT_DEX increases hit base, slightly */
5757 return get_dex() / 4.0f;
5758}

References get_dex().

Referenced by get_melee_hit_base().

◆ get_hit_weapon()

float Character::get_hit_weapon ( const item weap) const

Gets melee accuracy component from weapon+skills.

Unarmed improves hit chance for unarmed weapons Bashing improves hit chance for bashing weapons Cutting improves hit chance for cutting weapons Stabbing improves hit chance for piercing weapons Melee improves hit chance for all items (including non-weapons)

Definition at line 335 of file melee.cpp.

336{
337 /** @EFFECT_UNARMED improves hit chance for unarmed weapons */
338 /** @EFFECT_BASHING improves hit chance for bashing weapons */
339 /** @EFFECT_CUTTING improves hit chance for cutting weapons */
340 /** @EFFECT_STABBING improves hit chance for piercing weapons */
341 auto skill = get_skill_level( weap.melee_skill() );
342
343 // CQB bionic acts as a lower bound providing item uses a weapon skill
344 if( skill < BIO_CQB_LEVEL && has_active_bionic( bio_cqb ) ) {
345 skill = BIO_CQB_LEVEL;
346 }
347
348 /** @EFFECT_MELEE improves hit chance for all items (including non-weapons) */
349 return ( skill / 3.0f ) + ( get_skill_level( skill_melee ) / 2.0f ) + weap.type->m_to_hit;
350}

References bio_cqb, BIO_CQB_LEVEL, get_skill_level(), has_active_bionic(), itype::m_to_hit, item::melee_skill(), skill_melee, and item::type.

Referenced by item::effective_dps(), and get_melee_hit_base().

◆ get_hostile_creatures()

std::vector< Creature * > Character::get_hostile_creatures ( int  range) const

Get all hostile creatures currently visible to this player.

Definition at line 10242 of file character.cpp.

10243{
10244 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10245 // Fixes circular distance range for ranged attacks
10246 float dist_to_creature = std::round( rl_dist_exact( pos(), critter.pos() ) );
10247 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10248 dist_to_creature <= range && critter.attitude_to( *this ) == A_HOSTILE
10249 && sees( critter );
10250 } );
10251}
@ range
Definition: character.h:104
virtual Attitude attitude_to(const Creature &other) const =0
Attitude (of this creature) towards another creature.
float rl_dist_exact(const tripoint &loc1, const tripoint &loc2)
Definition: line.cpp:292

References Creature::A_HOSTILE, Creature::attitude_to(), g, Creature::pos(), pos(), range, rl_dist_exact(), and sees().

◆ get_hunger_description()

std::pair< std::string, nc_color > Character::get_hunger_description ( ) const

Definition at line 4386 of file character.cpp.

4387{
4388 int total_kcal = stored_calories + stomach.get_calories();
4389 int max_kcal = max_stored_kcal();
4390 float days_left = static_cast<float>( total_kcal ) / bmr();
4391 float days_max = static_cast<float>( max_kcal ) / bmr();
4392 std::string hunger_string;
4393 nc_color hunger_color = c_white;
4394 if( days_left >= days_max ) {
4395 hunger_string = _( "Engorged" );
4396 hunger_color = c_green;
4397 } else if( days_max - days_left < 0.5f ) {
4398 hunger_string = _( "Sated" );
4399 hunger_color = c_green;
4400 } else if( days_max - days_left < 1.0f ) {
4401 hunger_string = _( "Hungry" );
4402 hunger_color = c_yellow;
4403 } else if( days_max / days_left < 2.0f ) {
4404 hunger_string = _( "Very Hungry" );
4405 hunger_color = c_yellow;
4406 } else if( days_left > 1 ) {
4407 hunger_string = _( "Famished" );
4408 hunger_color = c_light_red;
4409 } else {
4410 hunger_string = _( "Starving" );
4411 hunger_color = c_red;
4412 }
4413
4414 if( has_trait( trait_SELFAWARE ) ) {
4415 hunger_string = string_format( "%d kcal", total_kcal );
4416 }
4417
4418 return std::make_pair( hunger_string, hunger_color );
4419}
static const trait_id trait_SELFAWARE("SELFAWARE")

References _, bmr(), c_green, c_light_red, c_red, c_white, c_yellow, stomach_contents::get_calories(), has_trait(), max_stored_kcal(), stomach, stored_calories, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_int()

◆ get_int_base()

int Character::get_int_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4118 of file character.cpp.

4119{
4120 return int_max;
4121}

References int_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_int(), and avatar::get_int_base().

◆ get_int_bonus()

int Character::get_int_bonus ( ) const
virtual

Definition at line 4135 of file character.cpp.

4136{
4137 return int_bonus;
4138}

References int_bonus.

Referenced by reset_stats().

◆ get_item_position()

int Character::get_item_position ( const item it) const

Returns the item position (suitable for i_at or similar) of a specific item.

Returns INT_MIN if the item is not found. Note that this may lose some information, for example the returned position is the same when the given item points to the container and when it points to the item inside the container. All items that are part of the same stack have the same item position.

Definition at line 2355 of file character.cpp.

2356{
2357 const item &weapon = primary_weapon();
2358 if( weapon.has_item( *it ) ) {
2359 return -1;
2360 }
2361
2362 int p = 0;
2363 for( const auto &e : worn ) {
2364 if( e.has_item( *it ) ) {
2365 return worn_position_to_index( p );
2366 }
2367 p++;
2368 }
2369
2370 return inv.position_by_item( it );
2371}
static int worn_position_to_index(int position)
Definition: character.h:1092
bool has_item(const item &it) const
Returns true if this visitable instance contains the item.
Definition: visitable.cpp:96

References visitable< T >::has_item(), inv, inventory::position_by_item(), primary_weapon(), worn, and worn_position_to_index().

Referenced by npc::alt_attack(), game::butcher(), iuse::chop_logs(), iuse::chop_tree(), chop_tree_activity(), convert_to_items(), damage_item(), iuse::fill_pit(), iuse::hacksaw(), monexamine::insert_battery(), iuse::makemound(), item_location::impl::item_on_person::obtain(), iuse::pack_item(), iuse::play_game(), iuse::radglove(), iuse::stimpack(), salvage_actor::try_to_cut_up(), pick_lock_actor::use(), musical_instrument_actor::use(), repair_item_actor::use(), sew_advanced_actor::use(), and avatar_action::wield().

◆ get_kcal_percent()

◆ get_learned_recipes()

const recipe_subset & Character::get_learned_recipes ( ) const

Returns all known recipes.

Definition at line 10587 of file character.cpp.

10588{
10589 if( *_skills != *autolearn_skills_stamp ) {
10590 for( const auto &r : recipe_dict.all_autolearn() ) {
10591 if( meets_skill_requirements( r->autolearn_requirements ) ) {
10592 learned_recipes->include( r );
10593 }
10594 }
10596 }
10597
10598 return *learned_recipes;
10599}
pimpl< recipe_subset > learned_recipes
Subset of learned recipes.
Definition: character.h:2175
pimpl< SkillLevelMap > autolearn_skills_stamp
Stamp of character skills.
Definition: character.h:2173
const std::set< const recipe * > & all_autolearn() const
Returns all recipes that can be automatically learned.

References _skills, recipe_dictionary::all_autolearn(), autolearn_skills_stamp, learned_recipes, meets_skill_requirements(), and recipe_dict.

Referenced by player::get_available_recipes(), knows_recipe(), peek_related_recipe(), and select_crafting_recipe().

◆ get_lowest_hp()

int Character::get_lowest_hp ( ) const

Definition at line 10381 of file character.cpp.

10382{
10383 // Set lowest_hp to an arbitrarily large number.
10384 int lowest_hp = 999;
10385 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
10386 const int cur_hp = elem.second.get_hp_cur();
10387 if( cur_hp < lowest_hp ) {
10388 lowest_hp = cur_hp;
10389 }
10390 }
10391 return lowest_hp;
10392}

References Creature::get_body().

Referenced by debug_menu::character_edit_menu().

◆ get_max_healthy()

int Character::get_max_healthy ( ) const

Definition at line 4568 of file character.cpp.

4569{
4570 return 200;
4571}

Referenced by update_health().

◆ get_max_power_level()

◆ get_melee()

float Character::get_melee ( ) const
overridevirtual

Returns melee skill level, to be used to throttle dodge practice.

Implements Creature.

Definition at line 914 of file melee.cpp.

915{
916 return get_skill_level( skill_id( "melee" ) );
917}

References get_skill_level(), and skill_id.

Referenced by stability_roll().

◆ get_melee_hit_base()

float Character::get_melee_hit_base ( ) const

Returns weapon skill.

Definition at line 352 of file melee.cpp.

353{
354 // Character::get_hit_base includes stat calculations already
356}
item & used_weapon()
Legacy code hack, don't use.
Definition: melee.cpp:145
float get_hit_weapon(const item &weap) const
Gets melee accuracy component from weapon+skills.
Definition: melee.cpp:335
float get_hit_base() const override
Definition: character.cpp:5754
float mabuff_tohit_bonus() const
Returns the to hit bonus from martial arts buffs.

References get_hit_base(), get_hit_weapon(), mabuff_tohit_bonus(), and used_weapon().

Referenced by draw_stats_info(), hit_roll(), and set_stats().

◆ get_miss_reason()

std::string Character::get_miss_reason ( )

Returns an explanation for why the player would miss a melee attack.

Definition at line 390 of file melee.cpp.

391{
392 // everything that lowers accuracy in player::hit_roll()
393 // adding it in hit_roll() might not be safe if it's called multiple times
394 // in one turn
396 _( "Your torso encumbrance throws you off-balance." ),
397 roll_remainder( encumb( bp_torso ) / 10.0 ) );
398 const int farsightedness = 2 * ( has_trait( trait_HYPEROPIC ) &&
399 !worn_with_flag( "FIX_FARSIGHT" ) &&
402 _( "You can't hit reliably due to your farsightedness." ),
403 farsightedness );
404
405 const std::string *const reason = melee_miss_reasons.pick();
406 if( reason == nullptr ) {
407 return std::string();
408 }
409 return *reason;
410}
void add_miss_reason(const std::string &reason, unsigned int weight)
Adds a reason for why the player would miss a melee attack.
Definition: melee.cpp:379
static const efftype_id effect_contacts("contacts")
static const trait_id trait_HYPEROPIC("HYPEROPIC")

References _, add_miss_reason(), bp_torso, effect_contacts, encumb(), Creature::has_effect(), has_trait(), melee_miss_reasons, roll_remainder(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack().

◆ get_mod()

int Character::get_mod ( const trait_id mut,
const std::string &  arg 
) const
private

Retrieves a stat mod of a mutation.

Definition at line 193 of file mutation.cpp.

194{
195 auto &mod_data = mut->mods;
196 int ret = 0;
197 auto found = mod_data.find( std::make_pair( false, arg ) );
198 if( found != mod_data.end() ) {
199 ret += found->second;
200 }
201 return ret;
202}
detail::named_arg< Char, T > arg(const Char *name, const T &arg)
\rst Returns a named argument to be used in a formatting function.
Definition: fmtlib_core.h:1860
std::unordered_map< std::pair< bool, std::string >, int, cata::tuple_hash > mods
Key pair is <active: bool, mod type: "STR">
Definition: mutation.h:277

References arg(), mutation_branch::mods, and cata::hash64_detail::ret.

Referenced by apply_mods().

◆ get_mod_stat_from_bionic()

int Character::get_mod_stat_from_bionic ( const character_stat Stat) const

Get stat bonus from bionic.

Definition at line 2116 of file character.cpp.

2117{
2118 int ret = 0;
2119 for( const bionic_id &bid : get_bionics() ) {
2120 const auto St_bn = bid->stat_bonus.find( Stat );
2121 if( St_bn != bid->stat_bonus.end() ) {
2122 ret += St_bn->second;
2123 }
2124 }
2125 return ret;
2126}

References get_bionics(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ get_morale()

int Character::get_morale ( const morale_type type) const

Definition at line 9114 of file character.cpp.

9115{
9116 return morale->get( type );
9117}

References morale, and type.

◆ get_morale_level()

int Character::get_morale_level ( ) const

◆ get_most_efficient_bionic()

bionic_id Character::get_most_efficient_bionic ( const std::vector< bionic_id > &  bids) const

Return bionic_id of bionic of most fuel efficient bionic.

Definition at line 1892 of file character.cpp.

1893{
1894 float temp_eff = 0;
1895 bionic_id bio( "null" );
1896 for( const bionic_id &bid : bids ) {
1897 if( bid->fuel_efficiency > temp_eff ) {
1898 temp_eff = bid->fuel_efficiency;
1899 bio = bid;
1900 }
1901 }
1902 return bio;
1903}

Referenced by fuel_bionic_with(), and get_acquirable_energy().

◆ get_movement_mode()

character_movemode Character::get_movement_mode ( ) const

Definition at line 1555 of file character.cpp.

1556{
1557 return move_mode;
1558}

References move_mode.

Referenced by cata_event_dispatch::avatar_moves().

◆ get_mutation_social_mods()

social_modifiers Character::get_mutation_social_mods ( ) const

Goes over all mutations, returning the sum of the social modifiers.

Definition at line 6567 of file character.cpp.

6568{
6569 social_modifiers mods;
6570 for( const mutation_branch *mut : cached_mutations ) {
6571 mods += mut->social_mods;
6572 }
6573
6574 return mods;
6575}

References cached_mutations.

Referenced by talk_trial::calc_chance().

◆ get_mutations()

std::vector< trait_id > Character::get_mutations ( bool  include_hidden = true) const

Get the idents of all traits/mutations.

Definition at line 2860 of file newcharacter.cpp.

2861{
2862 std::vector<trait_id> result;
2863 for( const std::pair<const trait_id, char_trait_data> &t : my_mutations ) {
2864 if( include_hidden || t.first.obj().player_display ) {
2865 result.push_back( t.first );
2866 }
2867 }
2868 for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) {
2869 if( include_hidden || ench_trait->player_display ) {
2870 bool found = false;
2871 for( const trait_id &exist : result ) {
2872 if( exist == ench_trait ) {
2873 found = true;
2874 break;
2875 }
2876 }
2877 if( !found ) {
2878 result.push_back( ench_trait );
2879 }
2880 }
2881 }
2882 return result;
2883}

References enchantment_cache, and my_mutations.

Referenced by monster::attitude(), bodytemp_modifier_traits(), bodytemp_modifier_traits_floor(), can_eat(), can_install_cbm_on_bp(), can_use_heal_item(), can_wear(), check_and_recover_morale(), compute_default_effective_vitamins(), player::crafting_success_roll(), avatar::create(), crossed_threshold(), character_display::disp_info(), drench_mut_calc(), npc::form_opinion(), has_trait_flag(), is_category_allowed(), is_weak_to_water(), mod_healthy(), mut_cbm_encumb(), mutation_armor(), mutation_attacks(), item::mutations_from_wearing(), diary::new_page(), process_turn(), avatar::randomize(), reset_scenario(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), set_description(), set_highest_cat_level(), set_profession(), sleep(), update_type_of_scent(), visible_mutations(), vitamin_rate(), and memorial_logger::write().

◆ get_name()

std::string Character::get_name ( ) const
overridevirtual

Implements Creature.

Definition at line 6004 of file character.cpp.

6005{
6006 return name;
6007}

References name.

Referenced by apply_damage(), autodoc_internal(), npc::die(), pour_into(), npc::set_omt_destination(), and game::vertical_move().

◆ get_next_auto_move_direction()

action_id Character::get_next_auto_move_direction ( )

Definition at line 10544 of file character.cpp.

10545{
10546 if( !has_destination() ) {
10547 return ACTION_NULL;
10548 }
10549
10551 if( pos() != *next_expected_position ) {
10552 // We're off course, possibly stumbling or stuck, cancel auto move
10553 return ACTION_NULL;
10554 }
10555 }
10556
10557 next_expected_position.emplace( auto_move_route.front() );
10558 auto_move_route.erase( auto_move_route.begin() );
10559
10561
10562 // Make sure the direction is just one step and that
10563 // all diagonal moves have 0 z component
10564 if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ||
10565 ( std::abs( dp.z ) != 0 && ( std::abs( dp.x ) != 0 || std::abs( dp.y ) != 0 ) ) ) {
10566 // Should never happen, but check just in case
10567 return ACTION_NULL;
10568 }
10570}
action_id get_movement_action_from_delta(const tripoint &d, const iso_rotate rot)
Translate coordinate delta into movement action.
Definition: action.cpp:492
@ ACTION_NULL
Invalid action used for various lookup errors.
Definition: action.h:20
int y
Definition: point.h:137
int z
Definition: point.h:138
int x
Definition: point.h:136

References ACTION_NULL, auto_move_route, get_movement_action_from_delta(), has_destination(), next_expected_position, pos(), tripoint::x, tripoint::y, yes, and tripoint::z.

Referenced by game::handle_action(), and game::try_get_left_click_action().

◆ get_npc_ai_info_cache()

std::optional< double > Character::get_npc_ai_info_cache ( npc_ai_info  key) const

Definition at line 10644 of file character.cpp.

10645{
10646 return npc_ai_info_cache[key];
10647}

References npc_ai_info_cache.

Referenced by npc::check_or_reload_cbm(), npc::find_reloadable(), npc::wield_better_weapon(), and npc_ai::wielded_value().

◆ get_overlay_ids()

std::vector< std::string > Character::get_overlay_ids ( ) const

Returns a list of the IDs of overlays on this character, sorted from "lowest" to "highest".

Only required for rendering.

Definition at line 3284 of file character.cpp.

3285{
3286 std::vector<std::string> rval;
3287 std::multimap<int, std::string> mutation_sorting;
3288 int order;
3289 std::string overlay_id;
3290
3291 // first get effects
3292 for( const auto &eff_pr : *effects ) {
3293 if( !eff_pr.second.begin()->second.is_removed() ) {
3294 rval.emplace_back( "effect_" + eff_pr.first.str() );
3295 }
3296 }
3297
3298 // then get mutations
3299 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
3300 overlay_id = ( mut.second.powered ? "active_" : "" ) + mut.first.str();
3301 order = get_overlay_order_of_mutation( overlay_id );
3302 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3303 }
3304
3305 // then get bionics
3306 for( const bionic &bio : *my_bionics ) {
3307 overlay_id = ( bio.powered ? "active_" : "" ) + bio.id.str();
3308 order = get_overlay_order_of_mutation( overlay_id );
3309 mutation_sorting.insert( std::pair<int, std::string>( order, overlay_id ) );
3310 }
3311
3312 for( auto &mutorder : mutation_sorting ) {
3313 rval.push_back( "mutation_" + mutorder.second );
3314 }
3315
3316 // next clothing
3317 // TODO: worry about correct order of clothing overlays
3318 for( const item &worn_item : worn ) {
3319 rval.push_back( "worn_" + worn_item.typeId().str() );
3320 }
3321
3322 // last weapon
3323 // TODO: might there be clothing that covers the weapon?
3324 const item &weapon = primary_weapon();
3325 if( is_armed() ) {
3326 rval.push_back( "wielded_" + weapon.typeId().str() );
3327 }
3328
3329 if( move_mode != CMM_WALK ) {
3330 rval.push_back( io::enum_to_string( move_mode ) );
3331 }
3332 return rval;
3333}
std::string enum_to_string(E)
int get_overlay_order_of_mutation(const std::string &mutation_id_string)

References CMM_WALK, Creature::effects, io::enum_to_string(), get_overlay_order_of_mutation(), is_armed(), move_mode, my_bionics, my_mutations, primary_weapon(), string_id< T >::str(), item::typeId(), and worn.

◆ get_pain_description()

std::pair< std::string, nc_color > Character::get_pain_description ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 4490 of file character.cpp.

4491{
4492 const std::pair<std::string, nc_color> pain = Creature::get_pain_description();
4493 nc_color pain_color = pain.second;
4494 std::string pain_string;
4495 // get pain color
4496 if( get_perceived_pain() >= 60 ) {
4497 pain_color = c_red;
4498 } else if( get_perceived_pain() >= 40 ) {
4499 pain_color = c_light_red;
4500 }
4501 // get pain string
4503 get_perceived_pain() > 0 ) {
4504 pain_string = string_format( "%s %d", _( "Pain " ), get_perceived_pain() );
4505 } else if( get_perceived_pain() > 0 ) {
4506 pain_string = pain.first;
4507 }
4508 return std::make_pair( pain_string, pain_color );
4509}
static const efftype_id effect_got_checked("got_checked")
virtual std::pair< std::string, nc_color > get_pain_description() const
Definition: creature.cpp:1417
int pain
Definition: creature.h:901

References _, c_light_red, c_red, effect_got_checked, Creature::get_pain_description(), get_perceived_pain(), Creature::has_effect(), has_trait(), Creature::pain, string_format(), and trait_SELFAWARE.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), and get_consume_needs_hint().

◆ get_painkiller()

int Character::get_painkiller ( ) const

◆ get_path_avoid()

std::set< tripoint > Character::get_path_avoid ( ) const
overridevirtual

Returns a set of points we do not want to path through.

Implements Creature.

Reimplemented in npc.

Definition at line 9961 of file character.cpp.

9962{
9963 std::set<tripoint> ret;
9964 for( npc &guy : g->all_npcs() ) {
9965 if( sees( guy ) ) {
9966 ret.insert( guy.pos() );
9967 }
9968 }
9969
9970 // TODO: Add known traps in a way that doesn't destroy performance
9971
9972 return ret;
9973}

References g, cata::hash64_detail::ret, and sees().

Referenced by activity_on_turn_move_loot(), can_mount(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route_adjacent(), activity_handlers::travel_do_turn(), and game::try_get_left_click_action().

◆ get_pathfinding_settings()

const pathfinding_settings & Character::get_pathfinding_settings ( ) const
overridevirtual

◆ get_per()

◆ get_per_base()

int Character::get_per_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4114 of file character.cpp.

4115{
4116 return per_max;
4117}

References per_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_per(), and avatar::get_per_base().

◆ get_per_bonus()

int Character::get_per_bonus ( ) const
virtual

Definition at line 4131 of file character.cpp.

4132{
4133 return per_bonus;
4134}

References per_bonus.

Referenced by reset_stats().

◆ get_perceived_pain()

int Character::get_perceived_pain ( ) const
overridevirtual

◆ get_power_level()

◆ get_rad()

◆ get_remote_fueled_bionic()

bionic_id Character::get_remote_fueled_bionic ( ) const

Returns bionic_id of first remote fueled bionic found.

Definition at line 1840 of file character.cpp.

1841{
1842 for( const bionic_id &bid : get_bionics() ) {
1843 if( bid->is_remote_fueled ) {
1844 return bid;
1845 }
1846 }
1847 return bionic_id();
1848}

References bionic_id, and get_bionics().

Referenced by iuse::cable_attach(), and iuse::solarpack().

◆ get_safe_reference()

safe_reference< Character > Character::get_safe_reference ( )

Definition at line 11064 of file character.cpp.

11065{
11066 return anchor.reference_to( this );
11067}
safe_reference_anchor anchor
Definition: character.h:2277
safe_reference< T > reference_to(T *object)

References anchor, and safe_reference_anchor::reference_to().

Referenced by itype::invoke().

◆ get_shout_volume()

int Character::get_shout_volume ( ) const
Strength increases shouting volume

Definition at line 7596 of file character.cpp.

7597{
7598 int base = 10;
7599 int shout_multiplier = 2;
7600
7601 // Mutations make shouting louder, they also define the default message
7602 if( has_trait( trait_SHOUT3 ) ) {
7603 shout_multiplier = 4;
7604 base = 20;
7605 } else if( has_trait( trait_SHOUT2 ) ) {
7606 base = 15;
7607 shout_multiplier = 3;
7608 }
7609
7610 // You can't shout without your face
7611 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7612 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7613 base = 0;
7614 shout_multiplier = 0;
7615 }
7616
7617 // Masks and such dampen the sound
7618 // Balanced around whisper for wearing bondage mask
7619 // and noise ~= 10 (door smashing) for wearing dust mask for character with strength = 8
7620 /** @EFFECT_STR increases shouting volume */
7621 const int penalty = encumb( bp_mouth ) * 3 / 2;
7622 int noise = base + str_cur * shout_multiplier - penalty;
7623
7624 // Minimum noise volume possible after all reductions.
7625 // Volume 1 can't be heard even by player
7626 constexpr int minimum_noise = 2;
7627
7628 if( noise <= base ) {
7629 noise = std::max( minimum_noise, noise );
7630 }
7631
7632 // Screaming underwater is not good for oxygen and harder to do overall
7633 if( is_underwater() ) {
7634 noise = std::max( minimum_noise, noise / 2 );
7635 }
7636 return noise;
7637}
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_SHOUT3("SHOUT3")

References bp_mouth, encumb(), has_trait(), Creature::is_underwater(), is_wearing(), itype_id, noise, str_cur, trait_PROF_FOODP, trait_SHOUT2, and trait_SHOUT3.

Referenced by game::chat(), npc::say(), shout(), and activity_handlers::spellcasting_finish().

◆ get_size()

◆ get_skill_level() [1/2]

int Character::get_skill_level ( const skill_id ident) const

Definition at line 3350 of file character.cpp.

3351{
3352 return _skills->get_skill_level( ident );
3353}

References _skills.

Referenced by npc::address_needs(), ranged::aim_speed_skill_modifier(), apply_skill_boost(), iexamine::arcfurnace_empty(), attack_cost(), avoid_trap(), mattack::bio_op_disarm(), bionics_pl_skill(), block_hit(), item::book_info(), ranged::burst_penalty(), activity_handlers::butcher_finish(), calc_skill_training_cost(), calc_skill_training_time(), veh_utils::calc_xp_gain(), character_martial_arts::can_arm_block(), can_autolearn_martial_art(), can_estimate_rot(), character_martial_arts::can_leg_block(), can_mount(), npc::can_read(), enzlave_actor::can_use(), caravan_price(), activity_handlers::chop_planks_finish(), item::color_in_inventory(), companion_combat_rank(), companion_industry_rank(), companion_survival_rank(), complete_craft(), crafting::complete_disassemble(), construction_color(), player::crafting_success_roll(), crit_chance(), iuse::crowbar(), salvage_actor::cut_up(), mattack::dermatik(), trap::detect_trap(), avatar::do_read(), dialogue::dynamic_line(), iuse::einktabletpc(), enumerate_unmet_requirements(), spell::exp_modifier(), map_data_common_t::extended_description(), npc::faction_display(), fall_damage_mod(), farm_action(), game::find_or_make_stairs(), npc::finish_read(), activity_handlers::fish_do_turn(), iuse::fish_trap(), item::food_info(), fungal_effects::fungalize(), player::get_available_recipes(), item::get_available_recipes(), heal_actor::get_bandaged_level(), avatar::get_book_reader(), heal_actor::get_disinfected_level(), get_dodge_base(), get_encumbrance_description(), heal_actor::get_heal_value(), get_hit_weapon(), get_melee(), player_activity::get_progress_message(), ranged::get_weapon_dispersion(), iuse::gun_repair(), avatar_funcs::gunmod_installation_odds(), computer_session::hack_attempt(), hack_level(), hackveh(), handle_melee_wear(), hardcoded_mutation_attack(), harvest_common(), iexamine::harvest_plant(), has_skill_for_vehicle_work(), ma_requirements::is_valid_character(), item_reload_cost(), item_store_cost(), ma_style_callback::key(), iexamine::kiln_empty(), activity_handlers::lockpicking_finish(), melee_attack(), avatar_funcs::mend_item(), iuse::mind_splicer(), morale_crafting_speed_multiplier(), iuse::multicooker(), mutation_attacks(), npc_trading::net_price_adjustment(), game::npc_menu(), on_dodge(), item::on_wield(), iuse::pack_cbm(), monexamine::pet_menu(), pick_part_to_heal(), pick_plant(), vehicle::pldrive(), practice(), iexamine::practice_survival_while_foraging(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), avatar::randomize(), examine_item_menu::rate_action_use(), reach_attack(), avatar::read(), recalc_hp(), repair_item_actor::repair(), repair_item_actor::repair_chance(), activity_handlers::repair_item_finish(), activity_handlers::robot_control_finish(), iuse::robotcontrol(), roll_bash_damage(), roll_cut_damage(), roll_stab_damage(), iexamine::safe(), scavenging_combat_skill(), set_description(), conditional_t< T >::set_has_skill(), set_skills(), map::shake_vehicle(), iexamine::shrub_wildveggies(), sinkhole_safety_roll(), skill_increment_cost(), skill_req_completed(), achievement::skill_ui_text(), npc::skills_offered_to(), smash(), read_inventory_preset::sort_compare(), spell::spell_fail(), player::start_craft(), talk_function::start_training(), suffer_from_schizophrenia(), survive_random_encounter(), swim_speed(), character_effects::talk_skill(), iuse::tazer(), ranged::throw_item(), throw_range(), mattack::thrown_by_judo(), ranged::time_to_attack(), known_magic::time_to_learn_spell(), npc::time_to_read(), avatar::time_to_read(), item::tname(), activity_handlers::train_finish(), iexamine::tree_hickory(), avatar_funcs::try_disarm_npc(), character_funcs::try_wield_contents(), veh_interact::update_part_requirements(), place_monster_iuse::use(), firestarter_actor::use(), enzlave_actor::use(), heal_actor::use(), sew_advanced_actor::use(), npc::value(), game::vertical_move(), and debug_menu::wishskill().

◆ get_skill_level() [2/2]

int Character::get_skill_level ( const skill_id ident,
const item context 
) const

Definition at line 3355 of file character.cpp.

3356{
3357 return _skills->get_skill_level( ident, context );
3358}

References _skills.

◆ get_skill_level_object() [1/2]

◆ get_skill_level_object() [2/2]

const SkillLevel & Character::get_skill_level_object ( const skill_id ident) const

Definition at line 3340 of file character.cpp.

3341{
3342 return _skills->get_skill_level_object( ident );
3343}

References _skills.

◆ get_sleep_deprivation()

int Character::get_sleep_deprivation ( ) const

Definition at line 4485 of file character.cpp.

4486{
4487 return sleep_deprivation;
4488}

References sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), check_needs_extremes(), hardcoded_effects(), reset_stats(), and suffer().

◆ get_speed()

◆ get_stamina()

◆ get_stamina_max()

int Character::get_stamina_max ( ) const

Definition at line 7098 of file character.cpp.

7099{
7100 static const std::string player_max_stamina( "PLAYER_MAX_STAMINA" );
7101 static const std::string max_stamina_modifier( "max_stamina_modifier" );
7102 const int baseMaxStamina = get_option< int >( player_max_stamina );
7103 int maxStamina = baseMaxStamina;
7104 maxStamina *= Character::mutation_value( max_stamina_modifier );
7105 maxStamina += bonus_from_enchantments( maxStamina, enchant_vals::mod::STAMINA_CAP );
7106 return std::max( baseMaxStamina / 10, maxStamina );
7107}

References bonus_from_enchantments(), mutation_value(), and enchant_vals::STAMINA_CAP.

Referenced by attack_cost(), block_hit(), can_run(), debug_menu::character_edit_menu(), cough(), player_activity::do_turn(), draw_char_narrow(), draw_char_wide(), draw_health_classic(), draw_limb2(), spell::energy_cost_string(), spell::energy_cur_string(), mod_stamina(), character_funcs::normalize(), on_dodge(), on_item_takeoff(), on_item_wear(), npc::process_turn(), activity_handlers::pulp_do_turn(), avatar::read(), speed_rating(), stamina_move_cost_modifier(), game::start_game(), iuse::stimpack(), ranged::time_to_attack(), update_stamina(), activity_handlers::wait_stamina_do_turn(), and activity_handlers::wait_stamina_finish().

◆ get_stashed_activity()

player_activity Character::get_stashed_activity ( ) const

Definition at line 908 of file character.cpp.

909{
911}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ get_stim()

◆ get_stored_kcal()

◆ get_str()

◆ get_str_base()

int Character::get_str_base ( ) const
virtual

Reimplemented in avatar.

Definition at line 4106 of file character.cpp.

4107{
4108 return str_max;
4109}

References str_max.

Referenced by enchantment::activate_passive(), draw_stats_tab(), get_str(), avatar::get_str_base(), and recalc_hp().

◆ get_str_bonus()

int Character::get_str_bonus ( ) const
virtual

Definition at line 4123 of file character.cpp.

4124{
4125 return str_bonus;
4126}

References str_bonus.

Referenced by reset_stats().

◆ get_thirst()

◆ get_thirst_description()

std::pair< std::string, nc_color > Character::get_thirst_description ( ) const

Definition at line 4357 of file character.cpp.

4358{
4359 int thirst = get_thirst();
4360 std::string hydration_string;
4361 nc_color hydration_color = c_white;
4363 hydration_color = c_light_red;
4364 hydration_string = _( "Parched" );
4365 } else if( thirst > thirst_levels::dehydrated ) {
4366 hydration_color = c_light_red;
4367 hydration_string = _( "Dehydrated" );
4368 } else if( thirst > thirst_levels::very_thirsty ) {
4369 hydration_color = c_yellow;
4370 hydration_string = _( "Very thirsty" );
4371 } else if( thirst > thirst_levels::thirsty ) {
4372 hydration_color = c_yellow;
4373 hydration_string = _( "Thirsty" );
4374 } else if( thirst > thirst_levels::slaked ) {
4375 // Nothing
4376 } else if( thirst > thirst_levels::hydrated ) {
4377 hydration_color = c_green;
4378 hydration_string = _( "Hydrated" );
4379 } else if( thirst > thirst_levels::turgid ) {
4380 hydration_color = c_green;
4381 hydration_string = _( "Turgid" );
4382 }
4383 return std::make_pair( hydration_string, hydration_color );
4384}

References _, c_green, c_light_red, c_white, c_yellow, dehydrated, get_thirst(), hydrated, parched, slaked, thirst, thirsty, turgid, and very_thirsty.

Referenced by draw_health_classic(), draw_needs_compact(), draw_needs_labels(), draw_needs_narrow(), npc::faction_display(), and get_consume_needs_hint().

◆ get_time_died()

time_point Character::get_time_died ( ) const
inline

return the calendar::turn the character expired

Definition at line 1473 of file character.h.

1473 {
1474 return time_died;
1475 }
time_point time_died
Definition: character.h:2185

References time_died.

◆ get_total_bionics_slots()

int Character::get_total_bionics_slots ( const bodypart_id bp) const

Definition at line 2570 of file bionics.cpp.

2571{
2572 return bp->bionic_slots();
2573}

Referenced by get_free_bionics_slots(), and show_bionics_ui().

◆ get_total_fuel_capacity()

int Character::get_total_fuel_capacity ( const itype_id fuel) const

Return total space to store specified fuel.

Definition at line 2054 of file character.cpp.

2055{
2056 int capacity = 0;
2057 for( const bionic_id &bid : get_bionics() ) {
2058 for( const itype_id &fl : bid->fuel_opts ) {
2059 if( get_value( bid.str() ).empty() || get_value( bid.str() ) == fl.str() ) {
2060 if( fl == fuel ) {
2061 capacity += bid->fuel_capacity;
2062 }
2063 }
2064 }
2065 }
2066 return capacity;
2067}

References get_bionics(), Creature::get_value(), and string_id< T >::str().

Referenced by draw_bionics_titlebar().

◆ get_type_of_scent()

scenttype_id Character::get_type_of_scent ( ) const

Definition at line 8766 of file character.cpp.

8767{
8768 return type_of_scent;
8769}
scenttype_id type_of_scent
Definition: character.h:2267

References type_of_scent.

Referenced by game::do_turn(), update_type_of_scent(), and change_scent_iuse::use().

◆ get_used_bionics_slots()

int Character::get_used_bionics_slots ( const bodypart_id bp) const

Definition at line 2542 of file bionics.cpp.

2543{
2544 int used_slots = 0;
2545 for( const bionic_id &bid : get_bionics() ) {
2546 auto search = bid->occupied_bodyparts.find( bp.id() );
2547 if( search != bid->occupied_bodyparts.end() ) {
2548 used_slots += search->second;
2549 }
2550 }
2551
2552 return used_slots;
2553}
static bool search(const ui_adaptor &om_ui, tripoint_abs_omt &curs, const tripoint_abs_omt &orig)

References get_bionics(), int_id< T >::id(), and overmap_ui::search().

Referenced by get_free_bionics_slots().

◆ get_visible_creatures()

std::vector< Creature * > Character::get_visible_creatures ( int  range) const

Returns all creatures that this player can see and that are in the given range.

This player object itself is never included. The player character (g->u) is checked and might be included (if applicable).

Parameters
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10234 of file character.cpp.

10235{
10236 return g->get_creatures_if( [this, range]( const Creature & critter ) -> bool {
10237 return this != &critter && pos() != critter.pos() && // TODO: get rid of fake npcs (pos() check)
10238 rl_dist( pos(), critter.pos() ) <= range && sees( critter );
10239 } );
10240}

References g, Creature::pos(), pos(), range, rl_dist(), and sees().

Referenced by game::is_hostile_within(), game::list_items_monsters(), and game::mon_info_update().

◆ get_vision_modes()

const std::bitset< NUM_VISION_MODES > & Character::get_vision_modes ( ) const
inline

Definition at line 1551 of file character.h.

1551 {
1552 return vision_mode_cache;
1553 }

References vision_mode_cache.

◆ get_vision_threshold()

float Character::get_vision_threshold ( float  light_level) const

Returns the apparent light level at which the player can see.

This is adjusted by the light level at the character's position to simulate glare, etc, night vision only works if you are in the dark.

Definition at line 1736 of file character.cpp.

1737{
1739 // Debug vision always works with absurdly little light.
1740 return 0.01;
1741 }
1742
1743 // As light_level goes from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LIT,
1744 // dimming goes from 1.0 to 2.0.
1745 const float dimming_from_light = 1.0 + ( ( static_cast<float>( light_level ) -
1748
1749 // -1 because SOME math was changed from LIGHT_AMBIENT_MINIMAL to LIGHT_AMBIENT_LOW
1750 // but kept in other places.
1751 // *_LOW is the one actually used in math, *_MINIMAL is arbitrary.
1752 // TODO: Correct test cases and drop the ugliness
1753
1754 // This guarantees at least 1 tile of range
1755 static const float threshold_cap = vision::threshold_for_nv_range( 1 - 1 ) * LIGHT_AMBIENT_LOW /
1757
1758 return std::min( {static_cast<float>( LIGHT_AMBIENT_LOW ),
1759 vision::threshold_for_nv_range( nv_range - 1 ) * dimming_from_light,
1760 threshold_cap} );
1761}
float nv_range
Definition: character.h:2180
static constexpr float LIGHT_AMBIENT_MINIMAL
Definition: lightmap.h:12
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
float threshold_for_nv_range(float range)
Returns the light level that darkness will have at this range from player.
Definition: character.cpp:1716

References DEBUG_NIGHTVISION, LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_AMBIENT_MINIMAL, nv_range, vision::threshold_for_nv_range(), and vision_mode_cache.

Referenced by sight_range().

◆ get_weight()

units::mass Character::get_weight ( ) const
overridevirtual

Returns body weight plus weight of inventory and worn/wielded items.

Implements Creature.

Definition at line 3688 of file character.cpp.

3689{
3690 units::mass ret = 0_gram;
3691 units::mass wornWeight = std::accumulate( worn.begin(), worn.end(), 0_gram,
3692 []( units::mass sum, const item & itm ) {
3693 return sum + itm.weight();
3694 } );
3695
3696 ret += bodyweight(); // The base weight of the player's body
3697 ret += inv.weight(); // Weight of the stored inventory
3698 ret += wornWeight; // Weight of worn items
3699 const item &weapon = primary_weapon();
3700 ret += weapon.weight(); // Weight of wielded item
3701 ret += bionics_weight(); // Weight of installed bionics
3702 return ret;
3703}
units::mass bionics_weight() const
Definition: character.cpp:6768
units::mass bodyweight() const
Definition: character.cpp:6763
units::mass weight() const
Definition: inventory.cpp:998

References bionics_weight(), bodyweight(), inv, primary_weapon(), cata::hash64_detail::ret, inventory::weight(), item::weight(), and worn.

Referenced by vehicle::calc_mass_center(), can_mount(), npc::move_to(), monexamine::pet_menu(), swim_speed(), weigh_self_actor::use(), and game::walk_move().

◆ get_weight_string()

std::string Character::get_weight_string ( ) const

Definition at line 4561 of file character.cpp.

4562{
4563 double weight = convert_weight( bodyweight() );
4564 int display_weight = static_cast<int>( std::round( weight ) );
4565 return std::to_string( display_weight ) + " " + weight_units();
4566}
const char * weight_units()
Create a units label for a weight value.
double convert_weight(const units::mass &weight)
Convert weight in grams to units defined by user (kg or lbs)

References bodyweight(), convert_weight(), to_string(), and weight_units().

◆ get_working_arm_count()

int Character::get_working_arm_count ( ) const

Returns the number of functioning arms.

Definition at line 1227 of file character.cpp.

1228{
1230 return 0;
1231 }
1232
1233 int limb_count = 0;
1234 if( !is_limb_disabled( bodypart_id( "arm_l" ) ) ) {
1235 limb_count++;
1236 }
1237 if( !is_limb_disabled( bodypart_id( "arm_r" ) ) ) {
1238 limb_count++;
1239 }
1240
1241 return limb_count;
1242}
static const trait_id trait_SHELL2("SHELL2")

References has_active_mutation(), is_limb_disabled(), and trait_SHELL2.

Referenced by can_wield(), has_two_arms(), melee_attack(), avatar_action::plthrow(), and vehicle::start_engine().

◆ get_working_leg_count()

int Character::get_working_leg_count ( ) const

Returns the number of functioning legs.

Definition at line 1245 of file character.cpp.

1246{
1247 int limb_count = 0;
1248 if( !is_limb_broken( bodypart_id( "leg_l" ) ) ) {
1249 limb_count++;
1250 }
1251 if( !is_limb_broken( bodypart_id( "leg_r" ) ) ) {
1252 limb_count++;
1253 }
1254 return limb_count;
1255}

References is_limb_broken().

Referenced by best_shield(), character_martial_arts::can_leg_block(), can_run(), is_on_ground(), and avatar::set_movement_mode().

◆ getID()

character_id Character::getID ( ) const

Definition at line 494 of file character.cpp.

495{
496 return this->id;
497}

References id.

Referenced by add_addiction(), item::already_used_by_player(), talk_effect_t::apply(), apply_damage(), iuse::artifact(), mission::assign(), talk_function::assign_camp(), vehicle::assign_seat(), best_installer(), bionics_install_failure(), map::board_vehicle(), veh_interact::calc_overview(), debug_menu::character_edit_menu(), check_needs_extremes(), talk_function::clear_mission(), game::critter_by_id(), iuse::crowbar(), mattack::dermatik(), monster::die(), npc::die(), avatar::do_read(), npc::execute_action(), dig_activity_actor::finish(), hacking_activity_actor::finish(), npc::finish_read(), ranged::fire_gun(), talk_function::follow(), item::get_remaining_chapters(), hardcoded_effects(), heal(), talk_function::hostile(), hurtall(), npc::is_ally(), item_location::impl::item_on_person::item_on_person(), talk_function::leave(), avatar::load(), game::load(), npc::load_npc_template(), item::mark_as_used_by_player(), item::mark_chapter_as_read(), iuse::marloss(), marloss_common(), iuse::marloss_gel(), iuse::marloss_seed(), iuse::mininuke(), mount_creature(), mutagen_common_checks(), mutate_towards(), npc::mutiny(), iuse::mycus(), iuse::note_bionics(), kill_tracker::notify(), talk_function::npc_die(), mattack::nurse_operate(), mission::on_creature_death(), item::on_pickup(), item::on_wield(), perform_install(), perform_uninstall(), practice(), npc::randomize(), avatar::read(), npc::regen_ai_cache(), rem_addiction(), Creature::remove_effect(), game::reset_npc_dispositions(), map::rotate(), talk_effect_fun_t::set_add_mission(), vehicle_part::set_crew(), npc::set_fac(), npc::set_known_to_u(), npc::setpos(), game::start_game(), npc::start_read(), talk_function::start_training(), talk_function::stop_guard(), player::store(), survive_random_encounter(), npc::talk_to_u(), teleport::teleport(), test_crossing_threshold(), ranged::throw_item(), activity_handlers::train_finish(), npc::travel_overmap(), game::validate_npc_followers(), vomit(), and wake_up().

◆ gibType()

field_type_id Character::gibType ( ) const
overridevirtual

Implements Creature.

Definition at line 524 of file character.cpp.

525{
526 return fd_gibs_flesh;
527}
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References fd_gibs_flesh.

◆ global_omt_location()

tripoint_abs_omt Character::global_omt_location ( ) const

Returns the location of the player in global overmap terrain coordinates.

Definition at line 6275 of file character.cpp.

6276{
6277 // TODO: fix point types
6279}
virtual tripoint global_square_location() const
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: character.cpp:6265
point ms_to_omt_copy(point p)
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493

References global_square_location(), and ms_to_omt_copy().

Referenced by talk_function::abandon_camp(), computer_session::action_map_sewer(), computer_session::action_map_subway(), computer_session::action_maps(), activate_bionic(), activate_mutation(), apply_persistent_morale(), iuse::artifact(), talk_function::assign_camp(), talk_function::basecamp_mission(), burn_fuel(), talk_function::caravan_dist(), ui::omap::choose_point(), talk_function::companion_choose_return(), talk_function::companion_list(), talk_function::companion_mission(), npc::consume_food_from_camp(), mission_start::create_hidden_lab_console(), mission_start::create_ice_lab_console(), mission_start::create_lab_console(), game::disp_NPCs(), item::display_name(), ui::omap::display_visible_weather(), ui::omap::display_weather(), game::do_turn(), overmap_ui::draw_ascii(), draw_env_compact(), draw_loc_labels(), draw_location_classic(), game::draw_minimap(), draw_minimap(), basecamp::faction_display(), npc::faction_display(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), mission_start::find_safety(), overmapbuffer::fix_npcs(), get_basecamp(), get_mission_om_origin(), overmapbuffer::get_npcs_near_omt(), overmapbuffer::get_npcs_near_player(), overmap_ui::get_overmap_path_to(), npc::go_to_omt_destination(), talk_function::goto_location(), npc::guard_current_pos(), talk_function::individual_mission(), mission_start::kill_horde_master(), game::list_missions(), spell_effect::map_area(), trapfunc::map_regen(), npc::move(), overmap_los(), passive_power_gen(), game::perhaps_add_random_npc(), mission_start::place_deposit_box(), mission_start::place_npc_software(), process_turn(), npc::reach_omt_destination(), talk_function::recover_camp(), teleporter_callback::refresh(), npc::regen_ai_cache(), render_wind(), game::reset_npc_dispositions(), reveal_destination(), mission_start::reveal_lab_train_depot(), mission_util::reveal_om_ter(), conditional_t< T >::set_at_om_location(), npc::set_companion_mission(), npc::set_omt_destination(), talk_function::start_camp(), game::start_game(), activity_handlers::travel_do_turn(), npc::travel_overmap(), activity_handlers::tree_communion_do_turn(), update_bodytemp(), game::update_overmap_seen(), reveal_map_actor::use(), game::vertical_notes(), iuse::weather_tool(), npc::within_boundaries_of_camp(), and game::zones_manager().

◆ global_sm_location()

tripoint Character::global_sm_location ( ) const

◆ global_square_location()

tripoint Character::global_square_location ( ) const
virtual

Global position, expressed in map square coordinate system (the most detailed coordinate system), used by the map.

Reimplemented in npc.

Definition at line 6265 of file character.cpp.

6266{
6267 return get_map().getabs( position );
6268}
tripoint position
Definition: character.h:2125

References get_map(), map::getabs(), and position.

Referenced by global_omt_location(), and global_sm_location().

◆ handle_melee_wear()

bool Character::handle_melee_wear ( item shield,
float  wear_multiplier = 1.0f 
)

Calculates melee weapon wear-and-tear through use, returns true if item is destroyed.

Dexterity reduces chance of damaging your melee weapon Strength increases chance of damaging your melee weapon (NEGATIVE) Melee reduces chance of damaging your melee weapon

Definition at line 217 of file melee.cpp.

218{
219 if( wear_multiplier <= 0.0f ) {
220 return false;
221 }
222 // Here is where we handle wear and tear on things we use as melee weapons or shields.
223 if( shield.is_null() ) {
224 return false;
225 }
226
227 // UNBREAKABLE_MELEE items can't be damaged through melee combat usage.
228 if( shield.has_flag( "UNBREAKABLE_MELEE" ) ) {
229 return false;
230 }
231
232 /** @EFFECT_DEX reduces chance of damaging your melee weapon */
233
234 /** @EFFECT_STR increases chance of damaging your melee weapon (NEGATIVE) */
235
236 /** @EFFECT_MELEE reduces chance of damaging your melee weapon */
237 const float stat_factor = dex_cur / 2.0f
239 + ( 64.0f / std::max( str_cur, 4 ) );
240
241 float material_factor;
242
243 itype_id weak_comp;
244 itype_id big_comp = itype_id::NULL_ID();
245 // Fragile items that fall apart easily when used as a weapon due to poor construction quality
246 if( shield.has_flag( "FRAGILE_MELEE" ) ) {
247 const float fragile_factor = 6;
248 int weak_chip = INT_MAX;
249 units::volume big_vol = 0_ml;
250
251 // Items that should have no bearing on durability
252 const std::set<itype_id> blacklist = { itype_rag, itype_leather, itype_fur };
253
254 for( auto &comp : shield.components ) {
255 if( blacklist.count( comp.typeId() ) <= 0 ) {
256 if( weak_chip > comp.chip_resistance() ) {
257 weak_chip = comp.chip_resistance();
258 weak_comp = comp.typeId();
259 }
260 }
261 if( comp.volume() > big_vol ) {
262 big_vol = comp.volume();
263 big_comp = comp.typeId();
264 }
265 }
266 material_factor = ( weak_chip < INT_MAX ? weak_chip : shield.chip_resistance() ) / fragile_factor;
267 } else {
268 material_factor = shield.chip_resistance();
269 }
270 int damage_chance = static_cast<int>( stat_factor * material_factor / wear_multiplier );
271 // DURABLE_MELEE items are made to hit stuff and they do it well, so they're considered to be a lot tougher
272 // than other weapons made of the same materials.
273 if( shield.has_flag( "DURABLE_MELEE" ) ) {
274 damage_chance *= 4;
275 }
276
277 if( damage_chance > 0 && !one_in( damage_chance ) ) {
278 return false;
279 }
280
281 auto str = shield.tname(); // save name before we apply damage
282
283 if( !shield.inc_damage() ) {
284 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the force of the blow!" ),
285 _( "<npcname>'s %s is damaged by the force of the blow!" ),
286 str );
287 return false;
288 }
289
290 // Dump its contents on the ground
291 // Destroy irremovable mods, if any
292
293 for( auto mod : shield.gunmods() ) {
294 if( mod->is_irremovable() ) {
295 remove_item( *mod );
296 }
297 }
298
299 // Preserve item temporarily for component breakdown
300 item temp = shield;
301
302 shield.contents.spill_contents( pos() );
303
304 remove_item( shield );
305
306 // Breakdown fragile weapons into components
307 if( temp.has_flag( "FRAGILE_MELEE" ) && !temp.components.empty() ) {
308 add_msg_player_or_npc( m_bad, _( "Your %s breaks apart!" ),
309 _( "<npcname>'s %s breaks apart!" ),
310 str );
311
312 for( auto &comp : temp.components ) {
313 int break_chance = comp.typeId() == weak_comp ? 2 : 8;
314
315 if( one_in( break_chance ) ) {
316 add_msg_if_player( m_bad, _( "The %s is destroyed!" ), comp.tname() );
317 continue;
318 }
319
320 if( comp.typeId() == big_comp && !is_armed() ) {
321 wield( comp );
322 } else {
323 g->m.add_item_or_charges( pos(), comp );
324 }
325 }
326 } else {
327 add_msg_player_or_npc( m_bad, _( "Your %s is destroyed by the blow!" ),
328 _( "<npcname>'s %s is destroyed by the blow!" ),
329 str );
330 }
331
332 return true;
333}
virtual bool wield(item &target)=0
Removes currently wielded item (if any) and replaces it with the target item.
bool spill_contents(const tripoint &pos)
int chip_resistance(bool worst=false) const
Returns resistance to being damaged by attack against the item itself.
Definition: item.cpp:6202
bool inc_damage(damage_type dt)
Increment item damage by itype::damage_scale constrained by max_damage.
Definition: item.cpp:6263
std::vector< item * > gunmods()
Returns all gunmods currently attached to this item (always empty if item not a gun)
Definition: item.cpp:7737
static const itype_id itype_rag("rag")
static const itype_id itype_fur("fur")
static const itype_id itype_leather("leather")

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::chip_resistance(), item::components, item::contents, dex_cur, g, get_skill_level(), item::gunmods(), item::has_flag(), item::inc_damage(), is_armed(), item::is_null(), itype_fur, itype_leather, itype_rag, m_bad, string_id< itype >::NULL_ID(), one_in(), pos(), visitable< Character >::remove_item(), skill_melee, item_contents::spill_contents(), str_cur, item::tname(), and wield().

Referenced by block_hit(), block_ranged_hit(), melee_special_effects(), reach_attack(), and smash().

◆ hardcoded_effects()

void Character::hardcoded_effects ( effect it)

Handles the still hard-coded effects.

Maximum Strength increases number of insects hatched from dermatik infection Intelligence decreases occurrence of itching from formication effect

Definition at line 471 of file player_hardcoded_effects.cpp.

472{
473 if( auto buff = ma_buff::from_effect( it ) ) {
474 if( buff->is_valid_character( *this ) ) {
475 buff->apply_character( *this );
476 } else {
477 it.set_duration( 0_turns ); // removes the effect
478 }
479 return;
480 }
481 using hc_effect_fun = std::function<void( player &, effect & )>;
482 static const std::map<efftype_id, hc_effect_fun> hc_effect_map = {{
495 }
496 };
497 const efftype_id &id = it.get_id();
498 const auto &iter = hc_effect_map.find( id );
499 if( iter != hc_effect_map.end() ) {
500 iter->second( *as_player(), it );
501 return;
502 }
503
504 const time_duration dur = it.get_duration();
505 int intense = it.get_intensity();
506 body_part bp = it.get_bp()->token;
507 bool sleeping = has_effect( effect_sleep );
508 if( id == effect_dermatik ) {
509 bool triggered = false;
510 int formication_chance = 3600;
511 if( dur < 4_hours ) {
512 formication_chance += 14400 - to_turns<int>( dur );
513 }
514 if( one_in( formication_chance ) ) {
515 add_effect( effect_formication, 60_minutes, bp );
516 }
517 if( dur < 1_days && one_in( 14400 ) ) {
518 vomit();
519 }
520 if( dur > 1_days ) {
521 // Spawn some larvae!
522 // Choose how many insects; more for large characters
523 ///\EFFECT_STR_MAX increases number of insects hatched from dermatik infection
524 int num_insects = rng( 1, std::min( 3, str_max / 3 ) );
525 apply_damage( nullptr, convert_bp( bp ).id(), rng( 2, 4 ) * num_insects );
526 // Figure out where they may be placed
528 _( "Your flesh crawls; insects tear through the flesh and begin to emerge!" ),
529 _( "Insects begin to emerge from <npcname>'s skin!" ) );
530 for( ; num_insects > 0; num_insects-- ) {
531 if( monster *const grub = g->place_critter_around( mon_dermatik_larva, pos(), 1 ) ) {
532 if( one_in( 3 ) ) {
533 grub->friendly = -1;
534 }
535 }
536 }
537 g->events().send<event_type::dermatik_eggs_hatch>( getID() );
539 moves -= 600;
540 triggered = true;
541 }
542 if( triggered ) {
543 // Set ourselves up for removal
544 it.set_duration( 0_turns );
545 } else {
546 // Count duration up
547 it.mod_duration( 1_turns );
548 }
549 } else if( id == effect_formication ) {
550 ///\EFFECT_INT decreases occurrence of itching from formication effect
551 if( x_in_y( intense, 600 + 300 * get_int() ) && !has_effect( effect_narcosis ) ) {
552 if( !is_npc() ) {
553 //~ %s is bodypart in accusative.
554 add_msg( m_warning, _( "You start scratching your %s!" ), body_part_name_accusative( bp ) );
555 g->u.cancel_activity();
556 } else if( g->u.sees( pos() ) ) {
557 //~ 1$s is NPC name, 2$s is bodypart in accusative.
558 add_msg( _( "%1$s starts scratching their %2$s!" ), name, body_part_name_accusative( bp ) );
559 }
560 moves -= 150;
561 apply_damage( nullptr, convert_bp( bp ).id(), 1 );
562 }
563 } else if( id == effect_evil ) {
564 // Worn or wielded; diminished effects
565 bool lesserEvil = primary_weapon().has_effect_when_wielded( AEP_EVIL ) ||
567 for( auto &w : worn ) {
568 if( w.has_effect_when_worn( AEP_EVIL ) ) {
569 lesserEvil = true;
570 break;
571 }
572 }
573 if( lesserEvil ) {
574 // Only minor effects, some even good!
575 mod_str_bonus( dur > 450_minutes ? 10.0 : dur / 45_minutes );
576 if( dur < 1_hours ) {
577 mod_dex_bonus( 1 );
578 } else {
579 int dex_mod = -( dur > 360_minutes ? 10.0 : ( dur - 1_hours ) / 30_minutes );
580 mod_dex_bonus( dex_mod );
581 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
582 }
583 mod_int_bonus( -( dur > 300_minutes ? 10.0 : ( dur - 50_minutes ) / 25_minutes ) );
584 mod_per_bonus( -( dur > 480_minutes ? 10.0 : ( dur - 80_minutes ) / 40_minutes ) );
585 } else {
586 // Major effects, all bad.
587 mod_str_bonus( -( dur > 500_minutes ? 10.0 : dur / 50_minutes ) );
588 int dex_mod = -( dur > 600_minutes ? 10.0 : dur / 60_minutes );
589 mod_dex_bonus( dex_mod );
590 add_miss_reason( _( "Why waste your time on that insignificant speck?" ), -dex_mod );
591 mod_int_bonus( -( dur > 450_minutes ? 10.0 : dur / 45_minutes ) );
592 mod_per_bonus( -( dur > 400_minutes ? 10.0 : dur / 40_minutes ) );
593 }
594 } else if( id == effect_attention ) {
595 if( intense > 6 ) {
596 if( one_in( 7200 - ( intense * 450 ) ) ) {
598 _( "You feel something reaching out to you, before reality around you frays!" ) );
599 if( has_psy_protection( *this, 10 ) ) {
600 // Transfers half of remaining duration of nether attention, tinfoil only sometimes helps
601 add_effect( effect_teleglow, ( dur / 2 ), num_bp, ( intense / 2 ) );
602 } else {
603 // Transfers all remaining duration of nether attention to dimensional instability
604 add_effect( effect_teleglow, dur, num_bp, intense );
605 }
606 it.set_duration( 0_turns );
607 }
608 if( one_in( 8000 - ( intense * 500 ) ) && one_in( 2 ) ) {
609 if( !is_npc() ) {
610 add_msg( m_bad, _( "You pass out from the strain of something bearing down on your mind." ) );
611 }
612 fall_asleep( 2_hours );
613 if( one_in( 10 ) ) {
614 it.set_duration( 0_turns );
615 }
616 it.mod_duration( -20_minutes * intense );
617 it.mod_intensity( -1 );
618 }
619 }
620 if( intense > 4 ) {
621 if( one_in( 6000 - ( intense * 375 ) ) ) {
622 if( has_psy_protection( *this, 4 ) ) {
623 add_msg_if_player( m_bad, _( "You feel something probing your mind, but it is rebuffed!" ) );
624 } else {
625 add_msg_if_player( m_bad, _( "A terrifying image in the back out your mind paralyzes you." ) );
627 moves -= 4 * get_speed();
628 }
629 it.mod_duration( -10_minutes * intense );
630 if( one_in( 2 ) ) {
631 it.mod_intensity( -1 );
632 }
633 }
634 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
635 if( has_psy_protection( *this, 4 ) ) {
636 add_msg_if_player( m_bad, _( "You feel a buzzing in the back of your mind, but it passes." ) );
637 } else {
638 add_msg_if_player( m_bad, _( "You feel something scream in the back of your mind!" ) );
639 add_effect( effect_dazed, rng( 1_minutes, 2_minutes ) );
640 }
641 it.mod_duration( -10_minutes * intense );
642 if( one_in( 3 ) ) {
643 it.mod_intensity( -1 );
644 }
645 }
646 }
647 if( intense > 2 ) {
648 if( one_turn_in( 1200_minutes - ( intense * 90_minutes ) ) ) {
649 add_msg_if_player( m_bad, _( "Your vision is filled with bright lights…" ) );
650 add_effect( effect_blind, rng( 1_minutes, 2_minutes ) );
651 it.mod_duration( -10_minutes * intense );
652 if( one_in( 4 ) ) {
653 it.mod_intensity( -1 );
654 }
655 }
656 if( one_in( 5000 ) && !has_effect( effect_nausea ) ) {
657 add_msg_if_player( m_bad, _( "A wave of nausea passes over you." ) );
658 add_effect( effect_nausea, 5_minutes );
659 }
660 }
661 if( one_in( 5000 ) && !has_effect( effect_hallu ) ) {
662 add_msg_if_player( m_bad, _( "Shifting shapes dance on the edge of your vision." ) );
663 add_effect( effect_hallu, 4_hours );
664 it.mod_duration( -10_minutes * intense );
665 }
666 if( one_turn_in( 40_minutes ) ) {
667 if( has_psy_protection( *this, 4 ) ) {
668 add_msg_if_player( m_bad, _( "You feel weird for a moment, but it passes." ) );
669 } else {
670 // Less morale drop and faster decay than Psychosis negative messages, but more frequent
671 const translation snip = SNIPPET.random_from_category( "nether_attention_watching" ).value_or(
672 translation() );
673 add_msg_if_player( m_warning, "%s", snip );
674 add_morale( MORALE_FEELING_BAD, -10, -50, 60_minutes, 20_minutes, true );
675 }
676 }
677 } else if( id == effect_teleglow ) {
678 // Each teleportation increases intensity by 1, 2 intensities per tier of effect.
679 // TODO: Include a chance to teleport to the nether realm.
680 // TODO: This with regards to NPCS
681 if( !is_player() ) {
682 // NO, no teleporting around the player because an NPC has teleglow!
683 return;
684 }
685 if( intense > 6 ) {
686 if( one_in( 6000 - ( intense * 250 ) ) ) {
687 if( !is_npc() ) {
688 add_msg( _( "Glowing lights surround you, and you teleport." ) );
689 }
690 teleport::teleport( *this );
691 g->events().send<event_type::teleglow_teleports>( getID() );
692 if( one_in( 10 ) ) {
693 // Set ourselves up for removal
694 it.set_duration( 0_turns );
695 }
696 // Since teleporting grants 1 intensity and 30 minutes duration,
697 // if it doesn't remove it'll get more intense but shorter.
698 it.mod_duration( -20_minutes * intense );
699 }
700 if( one_in( 7200 - ( intense * 250 ) ) ) {
701 add_msg_if_player( m_bad, _( "You are beset with a vision of a prowling beast." ) );
702 for( const tripoint &dest : g->m.points_in_radius( pos(), 6 ) ) {
703 if( g->m.is_cornerfloor( dest ) ) {
704 g->m.add_field( dest, fd_tindalos_rift, 3 );
705 add_msg_if_player( m_info, _( "Your surroundings are permeated with a foul scent." ) );
706 break;
707 }
708 }
709 if( one_in( 2 ) ) {
710 // Set ourselves up for removal
711 it.set_duration( 0_turns );
712 }
713 it.mod_intensity( -1 );
714 }
715 }
716 if( intense > 4 ) {
717 // Once every 4 hours baseline, once every 2 hours max
718 if( one_turn_in( 14_hours - ( intense * 90_minutes ) ) ) {
719 tripoint dest( 0, 0, posz() );
720 int &x = dest.x;
721 int &y = dest.y;
722 int tries = 0;
723 do {
724 x = posx() + rng( -4, 4 );
725 y = posy() + rng( -4, 4 );
726 tries++;
727 if( tries >= 10 ) {
728 break;
729 }
730 } while( g->critter_at( dest ) );
731 if( tries < 10 ) {
732 if( g->m.impassable( dest ) ) {
733 g->m.make_rubble( dest, f_rubble_rock );
734 }
736 GROUP_NETHER );
737 g->place_critter_at( spawn_details.name, dest );
738 if( g->u.sees( dest ) ) {
739 g->cancel_activity_or_ignore_query( distraction_type::hostile_spotted_far,
740 _( "A monster appears nearby!" ) );
741 add_msg( m_warning, _( "A portal opens nearby, and a monster crawls through!" ) );
742 }
743 it.mod_duration( -10_minutes * intense );
744 it.mod_intensity( -1 );
745 }
746 }
747 if( one_in( 21000 - ( intense * 1125 ) ) ) {
748 add_msg_if_player( m_bad, _( "You shudder suddenly." ) );
749 mutate();
750 it.mod_duration( -10_minutes * intense );
751 if( one_in( 2 ) ) {
752 it.mod_intensity( -1 );
753 }
754 }
755 }
756 if( intense > 2 ) {
757 if( one_in( 10000 ) ) {
758 if( !has_trait( trait_M_IMMUNE ) ) {
759 add_effect( effect_fungus, 1_turns, num_bp );
760 add_msg_if_player( m_bad, _( "You smell mold, and your skin itches." ) );
761 } else {
762 add_msg_if_player( m_info, _( "We have many colonists awaiting passage." ) );
763 }
764 // Set ourselves up for removal
765 it.set_duration( 0_turns );
766 }
767 if( one_in( 5000 ) ) {
768 // Like with the glow anomaly trap, but lower max and bypasses radsuits
769 add_msg_if_player( m_bad, _( "A blue flash of radiation permeates your vision briefly!" ) );
770 irradiate( rng( 10, 20 ), true );
771 it.mod_duration( -10_minutes * intense );
772 if( one_in( 4 ) ) {
773 it.mod_intensity( -1 );
774 }
775 }
776 }
777 if( one_in( 4000 ) ) {
778 add_msg_if_player( m_bad, _( "You're suddenly covered in ectoplasm." ) );
779 add_effect( effect_boomered, 10_minutes );
780 it.mod_duration( -10_minutes * intense );
781 }
782 if( one_in( 5000 ) ) {
783 add_msg_if_player( m_bad, _( "A strange sound reverberates around the edges of reality." ) );
784 // Comparable to the humming anomaly trap, with a narrower range
785 int volume = rng( 25, 150 );
786 std::string sfx;
787 if( volume <= 50 ) {
788 sfx = _( "hrmmm" );
789 } else if( volume <= 100 ) {
790 sfx = _( "HRMMM" );
791 } else {
792 sfx = _( "VRMMMMMM" );
793 }
794 sounds::sound( pos(), volume, sounds::sound_t::activity, sfx, false, "humming", "machinery" );
795 }
796 } else if( id == effect_asthma ) {
798 add_msg_if_player( m_good, _( "Your asthma attack stops." ) );
799 it.set_duration( 0_turns );
800 } else if( dur > 2_hours ) {
801 add_msg_if_player( m_bad, _( "Your asthma overcomes you.\nYou asphyxiate." ) );
802 g->events().send<event_type::dies_from_asthma_attack>( getID() );
803 hurtall( 500, nullptr );
804 } else if( dur > 70_minutes ) {
805 if( one_in( 120 ) ) {
806 add_msg_if_player( m_bad, _( "You wheeze and gasp for air." ) );
807 }
808 }
809 } else if( id == effect_brainworms ) {
810 if( one_in( 1536 ) ) {
811 add_msg_if_player( m_bad, _( "Your head aches faintly." ) );
812 }
813 if( one_in( 6144 ) ) {
814 mod_healthy_mod( -10, -100 );
815 apply_damage( nullptr, bodypart_id( "head" ), rng( 0, 1 ) );
816 if( !has_effect( effect_visuals ) ) {
817 add_msg_if_player( m_bad, _( "Your vision is getting fuzzy." ) );
818 add_effect( effect_visuals, rng( 1_minutes, 60_minutes ) );
819 }
820 }
821 if( one_in( 24576 ) ) {
822 mod_healthy_mod( -10, -100 );
823 apply_damage( nullptr, bodypart_id( "head" ), rng( 1, 2 ) );
824 if( !is_blind() && !sleeping ) {
825 add_msg_if_player( m_bad, _( "Your vision goes black!" ) );
826 add_effect( effect_blind, rng( 5_turns, 20_turns ) );
827 }
828 }
829 } else if( id == effect_tapeworm ) {
830 if( one_in( 3072 ) ) {
831 add_msg_if_player( m_bad, _( "Your bowels ache." ) );
832 }
833 } else if( id == effect_bloodworms ) {
834 if( one_in( 3072 ) ) {
835 add_msg_if_player( m_bad, _( "Your veins itch." ) );
836 }
837 } else if( id == effect_paincysts ) {
838 if( one_in( 3072 ) ) {
839 add_msg_if_player( m_bad, _( "Your muscles feel like they're knotted and tired." ) );
840 }
841 } else if( id == effect_datura ) {
842 if( dur > 100_minutes && focus_pool >= 1 && one_in( 24 ) ) {
843 focus_pool--;
844 }
845 if( dur > 200_minutes && one_in( 48 ) && get_stim() < 20 ) {
846 mod_stim( 1 );
847 }
848 if( dur > 300_minutes && focus_pool >= 1 && one_in( 12 ) ) {
849 focus_pool--;
850 }
851 if( dur > 400_minutes && one_in( 384 ) ) {
852 mod_pain( rng( -1, -8 ) );
853 }
854 if( ( !has_effect( effect_hallu ) ) && ( dur > 500_minutes && one_in( 24 ) ) ) {
855 add_effect( effect_hallu, 6_hours );
856 }
857 if( dur > 600_minutes && one_in( 768 ) ) {
858 mod_pain( rng( -3, -24 ) );
859 if( dur > 800_minutes && one_in( 16 ) ) {
861 _( "You're experiencing loss of basic motor skills and blurred vision. Your mind recoils in horror, unable to communicate with your spinal column." ) );
862 add_msg_if_player( m_bad, _( "You stagger and fall!" ) );
863 add_effect( effect_downed, rng( 1_turns, 4_turns ), num_bp, 0, true );
864 if( one_in( 8 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
865 vomit();
866 }
867 }
868 }
869 if( dur > 700_minutes && focus_pool >= 1 ) {
870 focus_pool--;
871 }
872 if( dur > 800_minutes && one_in( 1536 ) ) {
873 add_effect( effect_visuals, rng( 4_minutes, 20_minutes ) );
874 mod_pain( rng( -8, -40 ) );
875 }
876 if( dur > 1200_minutes && one_in( 1536 ) ) {
877 add_msg_if_player( m_bad, _( "There's some kind of big machine in the sky." ) );
878 add_effect( effect_visuals, rng( 8_minutes, 40_minutes ) );
879 if( one_in( 32 ) ) {
880 add_msg_if_player( m_bad, _( "It's some kind of electric snake, coming right at you!" ) );
881 mod_pain( rng( 4, 40 ) );
882 vomit();
883 }
884 }
885 if( dur > 1400_minutes && one_in( 768 ) ) {
887 _( "Order us some golf shoes, otherwise we'll never get out of this place alive." ) );
888 add_effect( effect_visuals, rng( 40_minutes, 200_minutes ) );
889 if( one_in( 8 ) ) {
891 _( "The possibility of physical and mental collapse is now very real." ) );
892 if( one_in( 2 ) || x_in_y( character_effects::vomit_mod( *this ), 10 ) ) {
893 add_msg_if_player( m_bad, _( "No one should be asked to handle this trip." ) );
894 vomit();
895 mod_pain( rng( 8, 40 ) );
896 }
897 }
898 }
899
900 if( dur > 1800_minutes && one_in( 300 * 512 ) ) {
901 if( !has_trait( trait_NOPAIN ) ) {
903 _( "Your heart spasms painfully and stops, dragging you back to reality as you die." ) );
904 } else {
906 _( "You dissolve into beautiful paroxysms of energy. Life fades from your nebulae and you are no more." ) );
907 }
908 g->events().send<event_type::dies_from_drug_overdose>( getID(), id );
909 set_part_hp_cur( bodypart_id( "torso" ), 0 );
910 }
911 } else if( id == effect_grabbed ) {
913 int zed_number = 0;
914 for( auto &dest : g->m.points_in_radius( pos(), 1, 0 ) ) {
915 const monster *const mon = g->critter_at<monster>( dest );
916 if( mon && mon->has_effect( effect_grabbing ) ) {
917 zed_number += mon->get_grab_strength();
918 }
919 }
920 if( zed_number > 0 ) {
921 //If intensity isn't pass the cap, average it with # of zeds
922 add_effect( effect_grabbed, 2_turns, bp_torso, ( intense + zed_number ) / 2 );
923 }
924 } else if( id == effect_bite ) {
925 bool recovered = false;
926 /* Recovery chances, use binomial distributions if balancing here. Healing in the bite
927 * stage provides additional benefits, so both the bite stage chance of healing and
928 * the cumulative chances for spontaneous healing are both given.
929 * Cumulative heal chances for the bite + infection stages:
930 * -200 health - 38.6%
931 * 0 health - 46.8%
932 * 200 health - 53.7%
933 *
934 * Heal chances in the bite stage:
935 * -200 health - 23.4%
936 * 0 health - 28.3%
937 * 200 health - 32.9%
938 *
939 * Cumulative heal chances the bite + infection stages with the resistant mutation:
940 * -200 health - 82.6%
941 * 0 health - 84.5%
942 * 200 health - 86.1%
943 *
944 * Heal chances in the bite stage with the resistant mutation:
945 * -200 health - 60.7%
946 * 0 health - 63.2%
947 * 200 health - 65.6%
948 */
949 if( dur % 10_turns == 0_turns ) {
950 int recover_factor = 100;
951 if( has_effect( effect_recover ) ) {
952 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
953 }
954 if( has_trait( trait_INFRESIST ) ) {
955 recover_factor += 200;
956 }
957 if( has_effect( effect_panacea ) ) {
958 recover_factor = 648000; //panacea is a guaranteed cure
959 } else if( has_effect( effect_strong_antibiotic ) ) {
960 recover_factor += 400;
961 } else if( has_effect( effect_antibiotic ) ) {
962 recover_factor += 200;
963 } else if( has_effect( effect_weak_antibiotic ) ) {
964 recover_factor += 100;
965 }
966 recover_factor += get_healthy() / 10;
967
968 if( x_in_y( recover_factor, 648000 ) ) {
969 //~ %s is bodypart name.
970 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
971 body_part_name( bp ) );
972 // Set ourselves up for removal
973 it.set_duration( 0_turns );
974 recovered = true;
975 }
976 }
977 if( !recovered ) {
978 // Move up to infection
979 // Infection resistance can keep us in bite phase arbitrarily long
980 if( dur > 6_hours && !has_trait( trait_INFRESIST ) ) {
981 add_effect( effect_infected, 1_turns, bp );
982 // Set ourselves up for removal
983 it.set_duration( 0_turns );
984 } else if( has_effect( effect_strong_antibiotic ) ) {
985 // Strong antibiotic reverses progress
986 it.mod_duration( -1_turns );
987 } else if( has_effect( effect_antibiotic ) ) {
988 // Normal antibiotic prevents progression
989 } else if( has_effect( effect_weak_antibiotic ) ) {
990 if( calendar::once_every( 4_turns ) ) {
991 // Weak antibiotic slows down to a quarter
992 it.mod_duration( 1_turns );
993 }
994 } else {
995 it.mod_duration( 1_turns );
996 }
997 }
998 } else if( id == effect_infected ) {
999 bool recovered = false;
1000 // Recovery chance, use binomial distributions if balancing here.
1001 // See "bite" for balancing notes on this.
1002 if( dur % 10_turns == 0_turns ) {
1003 int recover_factor = 100;
1004 if( has_effect( effect_recover ) ) {
1005 recover_factor -= get_effect_dur( effect_recover ) / 1_hours;
1006 }
1007 if( has_trait( trait_INFRESIST ) ) {
1008 recover_factor += 200;
1009 }
1010 if( has_effect( effect_panacea ) ) {
1011 recover_factor = 5184000;
1012 } else if( has_effect( effect_strong_antibiotic ) ) {
1013 recover_factor += 400;
1014 } else if( has_effect( effect_antibiotic ) ) {
1015 recover_factor += 200;
1016 } else if( has_effect( effect_weak_antibiotic ) ) {
1017 recover_factor += 100;
1018 }
1019 recover_factor += get_healthy() / 10;
1020
1021 if( x_in_y( recover_factor, 5184000 ) ) {
1022 //~ %s is bodypart name.
1023 add_msg_if_player( m_good, _( "Your %s wound begins to feel better!" ),
1024 body_part_name( bp ) );
1025 add_effect( effect_recover, 4 * dur );
1026 // Set ourselves up for removal
1027 it.set_duration( 0_turns );
1028 recovered = true;
1029 }
1030 }
1031 if( !recovered ) {
1032 // Don't kill if the player is on antibiotics
1034 it.mod_duration( -1_turns );
1035 } else if( has_effect( effect_antibiotic ) ) {
1036 // No progression
1037 } else if( has_effect( effect_weak_antibiotic ) ) {
1038 if( calendar::once_every( 4_turns ) ) {
1039 it.mod_duration( 1_turns );
1040 }
1041 } else if( dur > 1_days ) {
1042 add_msg_if_player( m_bad, _( "You succumb to the infection." ) );
1043 g->events().send<event_type::dies_of_infection>( getID() );
1044 hurtall( 500, nullptr );
1045 } else {
1046 it.mod_duration( 1_turns );
1047 }
1048 }
1049 } else if( id == effect_lying_down ) {
1050 set_moves( 0 );
1051 if( character_funcs::roll_can_sleep( *this ) ) {
1052 fall_asleep();
1053 // Set ourselves up for removal
1054 it.set_duration( 0_turns );
1055 }
1056 if( dur == 1_turns && !sleeping ) {
1057 add_msg_if_player( _( "You try to sleep, but can't…" ) );
1058 }
1059 } else if( id == effect_sleep ) {
1060 set_moves( 0 );
1061 if( is_avatar() ) {
1063 }
1064
1065 if( has_effect( effect_narcosis ) && get_fatigue() <= 25 ) {
1066 set_fatigue( 25 ); //Prevent us from waking up naturally while under anesthesia
1067 }
1068
1069 if( get_fatigue() <= 10 && !has_effect( effect_narcosis ) ) {
1070 set_fatigue( 0 );
1072 add_msg_if_player( m_good, _( "You feel well rested." ) );
1073 } else {
1075 _( "You feel physically rested, but you haven't been able to catch up on your missed sleep yet." ) );
1076 }
1077 it.set_duration( 0_seconds );
1078 }
1079
1080 // TODO: Move this to update_needs when NPCs can mutate
1081 if( calendar::once_every( 10_minutes ) && ( has_trait( trait_CHLOROMORPH ) ||
1083 g->m.is_outside( pos() ) ) {
1084 if( has_trait( trait_CHLOROMORPH ) ) {
1085 // Hunger and thirst fall before your Chloromorphic physiology!
1086 if( g->natural_light_level( posz() ) >= 12 &&
1087 get_weather().weather_id->sun_intensity >= sun_intensity_type::light ) {
1088 if( get_stored_kcal() < max_stored_kcal() - 50 ) {
1089 mod_stored_kcal( 50 );
1090 }
1092 mod_thirst( -5 );
1093 }
1094 }
1095 }
1096 if( has_trait( trait_M_SKIN3 ) ) {
1097 // Spores happen!
1098 if( g->m.has_flag_ter_or_furn( "FUNGUS", pos() ) ) {
1099 if( get_fatigue() >= 0 ) {
1100 mod_fatigue( -5 ); // Local guides need less sleep on fungal soil
1101 }
1102 if( calendar::once_every( 1_hours ) ) {
1103 spores(); // spawn some P O O F Y B O I S
1104 }
1105 }
1106 }
1107 if( has_trait( trait_WATERSLEEP ) ) {
1108 mod_fatigue( -3 ); // Fish sleep less in water
1109 }
1110 }
1111
1112 // Check mutation category strengths to see if we're mutated enough to get a dream
1113 std::string highcat = get_highest_category();
1114 int highest = mutation_category_level[highcat];
1115
1116 // Determine the strength of effects or dreams based upon category strength
1117 int strength = 0; // Category too weak for any effect or dream
1118 if( crossed_threshold() ) {
1119 strength = 4; // Post-human.
1120 } else if( highest >= 20 && highest < 35 ) {
1121 strength = 1; // Low strength
1122 } else if( highest >= 35 && highest < 50 ) {
1123 strength = 2; // Medium strength
1124 } else if( highest >= 50 ) {
1125 strength = 3; // High strength
1126 }
1127
1128 // Get a dream if category strength is high enough.
1129 if( strength != 0 ) {
1130 //Once every 6 / 3 / 2 hours, with a bit of randomness
1131 if( calendar::once_every( 6_hours / strength ) && one_in( 3 ) ) {
1132 // Select a dream
1133 std::string dream = dreams::get_random_for_category( highcat, strength );
1134 if( !dream.empty() ) {
1136 }
1137 // Mycus folks upgrade in their sleep.
1138 if( has_trait( trait_THRESH_MYCUS ) ) {
1139 if( one_in( 8 ) ) {
1140 mutate_category( "MYCUS" );
1141 mod_stored_nutr( 10 );
1142 mod_thirst( 10 );
1143 mod_fatigue( 5 );
1144 }
1145 }
1146 }
1147 }
1148
1149 bool woke_up = false;
1150 int tirednessVal = rng( 5, 200 ) + rng( 0, std::abs( get_fatigue() * 2 * 5 ) );
1151 if( !is_blind() && !has_effect( effect_narcosis ) ) {
1152 if( !has_trait(
1153 trait_SEESLEEP ) ) { // People who can see while sleeping are acclimated to the light.
1155 // So you can too sleep through noon
1156 if( ( tirednessVal * 1.25 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1157 one_in( get_fatigue() / 2 ) ) ) {
1158 add_msg_if_player( _( "It's too bright to sleep." ) );
1159 // Set ourselves up for removal
1160 it.set_duration( 0_turns );
1161 woke_up = true;
1162 }
1163 // Ursine hibernators would likely do so indoors. Plants, though, might be in the sun.
1164 } else if( has_trait( trait_HIBERNATE ) ) {
1165 if( ( tirednessVal * 5 ) < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1166 one_in( get_fatigue() / 2 ) ) ) {
1167 add_msg_if_player( _( "It's too bright to sleep." ) );
1168 // Set ourselves up for removal
1169 it.set_duration( 0_turns );
1170 woke_up = true;
1171 }
1172 } else if( tirednessVal < g->m.ambient_light_at( pos() ) && ( get_fatigue() < 10 ||
1173 one_in( get_fatigue() / 2 ) ) ) {
1174 add_msg_if_player( _( "It's too bright to sleep." ) );
1175 // Set ourselves up for removal
1176 it.set_duration( 0_turns );
1177 woke_up = true;
1178 }
1179 } else if( has_active_mutation( trait_SEESLEEP ) ) {
1180 Creature *hostile_critter = g->is_hostile_very_close();
1181 if( hostile_critter != nullptr ) {
1182 add_msg_if_player( _( "You see %s approaching!" ),
1183 hostile_critter->disp_name() );
1184 it.set_duration( 0_turns );
1185 woke_up = true;
1186 }
1187 }
1188 }
1189
1190 // Have we already woken up?
1191 if( !woke_up && !has_effect( effect_narcosis ) ) {
1192 // Cold or heat may wake you up.
1193 // Player will sleep through cold or heat if fatigued enough
1194 for( const body_part bp : all_body_parts ) {
1195 if( temp_cur[bp] < BODYTEMP_VERY_COLD - get_fatigue() / 2 ) {
1196 if( one_in( 30000 ) ) {
1197 add_msg_if_player( _( "You toss and turn trying to keep warm." ) );
1198 }
1199 if( temp_cur[bp] < BODYTEMP_FREEZING - get_fatigue() / 2 ||
1200 one_in( temp_cur[bp] * 6 + 30000 ) ) {
1201 add_msg_if_player( m_bad, _( "It's too cold to sleep." ) );
1202 // Set ourselves up for removal
1203 it.set_duration( 0_turns );
1204 woke_up = true;
1205 break;
1206 }
1207 } else if( temp_cur[bp] > BODYTEMP_VERY_HOT + get_fatigue() / 2 ) {
1208 if( one_in( 30000 ) ) {
1209 add_msg_if_player( _( "You toss and turn in the heat." ) );
1210 }
1211 if( temp_cur[bp] > BODYTEMP_SCORCHING + get_fatigue() / 2 ||
1212 one_in( 90000 - temp_cur[bp] ) ) {
1213 add_msg_if_player( m_bad, _( "It's too hot to sleep." ) );
1214 // Set ourselves up for removal
1215 it.set_duration( 0_turns );
1216 woke_up = true;
1217 break;
1218 }
1219 }
1220 }
1222 one_in( 43200 ) && is_player() ) ) {
1223 if( one_in( 2 ) ) {
1224 sound_hallu();
1225 } else {
1226 int max_count = rng( 1, 3 );
1227 int count = 0;
1228 for( const tripoint &mp : g->m.points_in_radius( pos(), 1 ) ) {
1229 if( mp == pos() ) {
1230 continue;
1231 }
1232 if( g->m.has_flag( "FLAT", mp ) &&
1233 g->m.pl_sees( mp, 2 ) ) {
1234 g->spawn_hallucination( mp );
1235 if( ++count > max_count ) {
1236 break;
1237 }
1238 }
1239 }
1240 }
1241 it.set_duration( 0_turns );
1242 woke_up = true;
1243 }
1244 }
1245
1246 // A bit of a hack: check if we are about to wake up for any reason, including regular
1247 // timing out of sleep
1248 if( dur == 1_turns || woke_up ) {
1249 wake_up();
1250 }
1251 } else if( id == effect_alarm_clock ) {
1252 if( in_sleep_state() ) {
1253 const bool asleep = has_effect( effect_sleep );
1254 if( has_bionic( bio_watch ) ) {
1255 if( dur == 1_turns ) {
1256 if( !asleep ) {
1257 add_msg_if_player( _( "Your internal chronometer went off and you haven't slept a wink." ) );
1259 } else {
1260 // Secure the flag before wake_up() clears the effect
1261 bool slept_through = has_effect( effect_slept_through_alarm );
1262 wake_up();
1263 if( slept_through ) {
1264 add_msg_if_player( _( "Your internal chronometer finally wakes you up." ) );
1265 } else {
1266 add_msg_if_player( _( "Your internal chronometer wakes you up." ) );
1267 }
1268 }
1269 }
1270 } else {
1271 if( asleep && dur == 1_turns ) {
1274 }
1275 // 10 minute automatic snooze
1276 it.mod_duration( 10_minutes );
1277 } else if( dur == 2_turns ) {
1278 // let the sound code handle the wake-up part
1279 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1280 "alarm_clock" );
1281 }
1282 }
1283 } else {
1284 if( dur == 1_turns ) {
1285 if( is_avatar() && has_alarm_clock() ) {
1286 sounds::sound( pos(), 16, sounds::sound_t::alarm, _( "beep-beep-beep!" ), false, "tool",
1287 "alarm_clock" );
1288 const std::string alarm = _( "Your alarm is going off." );
1289 g->cancel_activity_or_ignore_query( distraction_type::alert, alarm );
1290 add_msg( _( "Your alarm went off." ) );
1291 }
1292 }
1293 }
1294 } else if( id == effect_disabled ) {
1295 if( get_part_hp_cur( convert_bp( bp ) ) >= get_part_hp_max( convert_bp( bp ) ) ) {
1297 }
1298 } else if( id == effect_panacea ) {
1299 // restore health all body parts, dramatically reduce pain
1300 healall( 1 );
1301 mod_pain( -10 );
1302 }
1303}
bool has_psy_protection(const Character &c, int partial_chance)
Returns true if the player has a psyshield artifact, or sometimes if wearing tinfoil.
void mutate_category(const std::string &mut_cat)
Picks a random valid mutation in a category and mutate_towards() it.
Definition: mutation.cpp:1019
void sound_hallu()
Creates an auditory hallucination.
Definition: suffer.cpp:1660
void wake_up()
Removes "sleep" and "lying_down".
Definition: character.cpp:7583
int posz() const override
Definition: character.h:801
virtual void mod_per_bonus(int nper)
Definition: character.cpp:4209
virtual void mod_dex_bonus(int ndex)
Definition: character.cpp:4204
void mutate()
Picks a random valid mutation and gives it to the Character, possibly removing/changing others along ...
Definition: mutation.cpp:820
bool crossed_threshold() const
Returns true if the player has crossed a mutation threshold Player can only cross one mutation thresh...
Definition: character.cpp:8723
bool is_blind() const
Returns true if the player isn't able to see.
Definition: character.cpp:6281
bool has_alarm_clock() const
Returns true if the player or their vehicle has an alarm clock.
Definition: character.cpp:722
virtual void mod_str_bonus(int nstr)
Definition: character.cpp:4199
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7847
virtual void mod_stored_nutr(int nnutr)
Definition: character.cpp:4329
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8668
int get_speed() const override
Definition: character.cpp:4149
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1589
virtual void mod_int_bonus(int nint)
Definition: character.cpp:4214
virtual int get_num_blocks_bonus() const
Definition: creature.cpp:1489
virtual void set_num_blocks_bonus(int nblocks)
Definition: creature.cpp:1766
void set_moves(int nmoves)
Definition: creature.cpp:1453
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void mod_duration(const time_duration &dur, bool alert=false)
Mods the duration, capping at max_duration if it exists.
Definition: effect.cpp:821
time_duration get_duration() const
Returns the remaining duration of an effect.
Definition: effect.cpp:797
void set_duration(const time_duration &dur, bool alert=false)
Sets the duration, capping at max_duration if it exists.
Definition: effect.cpp:805
int mod_intensity(int mod, bool alert=false)
Modify intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:886
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
bool has_effect_when_carried(art_effect_passive effect) const
Does the item provide the artifact effect when it is carried?
Definition: item.cpp:9764
bool has_effect_when_wielded(art_effect_passive effect) const
Does the item provide the artifact effect when it is wielded?
Definition: item.cpp:9746
static const ma_buff * from_effect(const effect &eff)
int get_grab_strength() const
Definition: monster.cpp:2036
Definition: player.h:84
@ AEP_EVIL
Definition: enums.h:127
@ AEP_SCHIZO
Definition: enums.h:128
@ dies_from_asthma_attack
@ dermatik_eggs_hatch
@ teleglow_teleports
field_type_id fd_tindalos_rift
Definition: field_type.cpp:387
input_manager inp_mngr
Definition: input.cpp:109
furn_id f_rubble_rock
Definition: mapdata.cpp:1100
const morale_type MORALE_FEELING_BAD("morale_feeling_bad")
double vomit_mod(const Character &ch)
Returns the modifier value used for vomiting effects.
bool roll_can_sleep(Character &who)
Checked each turn during "lying_down", returns true if the avatar falls asleep.
constexpr size_t count()
Definition: fmtlib_core.h:1073
std::string get_random_for_category(const std::string &cat, int strength)
Returns a random dream description that matches given category and strength.
Definition: sounds.h:92
static const trait_id trait_M_SKIN3("M_SKIN3")
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_downed("downed")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_blind("blind")
static const efftype_id effect_datura("datura")
static const efftype_id effect_teleglow("teleglow")
static const efftype_id effect_dermatik("dermatik")
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_infected("infected")
static const efftype_id effect_cold("cold")
static const efftype_id effect_attention("attention")
static const efftype_id effect_recover("recover")
static const efftype_id effect_asthma("asthma")
static const efftype_id effect_antibiotic("antibiotic")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static void eff_fun_bloated(player &u, effect &it)
static const efftype_id effect_hallu("hallu")
static void eff_fun_cold(player &u, effect &it)
static const efftype_id effect_bite("bite")
static const mtype_id mon_dermatik_larva("mon_dermatik_larva")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const efftype_id effect_tapeworm("tapeworm")
static const efftype_id effect_boomered("boomered")
static const trait_id trait_HIBERNATE("HIBERNATE")
static const trait_id trait_SEESLEEP("SEESLEEP")
static const efftype_id effect_hot("hot")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static void eff_fun_hot(player &u, effect &it)
static void eff_fun_bleed(player &u, effect &it)
static const efftype_id effect_spores("spores")
static const efftype_id effect_evil("evil")
static const trait_id trait_INFRESIST("INFRESIST")
static const efftype_id effect_grabbing("grabbing")
static const efftype_id effect_weak_antibiotic("weak_antibiotic")
static void eff_fun_fungus(player &u, effect &it)
static const efftype_id effect_panacea("panacea")
static const efftype_id effect_visuals("visuals")
static const efftype_id effect_dazed("dazed")
static void eff_fun_toxin_buildup(player &u, effect &it)
static void eff_fun_spores(player &u, effect &it)
static const bionic_id bio_watch("bio_watch")
static const efftype_id effect_paincysts("paincysts")
static const efftype_id effect_toxin_buildup("toxin_buildup")
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_bloated("bloated")
static void eff_fun_mutating(player &u, effect &it)
static const efftype_id effect_fearparalyze("fearparalyze")
static const efftype_id effect_strong_antibiotic("strong_antibiotic")
static const trait_id trait_CHLOROMORPH("CHLOROMORPH")
static const trait_id trait_WATERSLEEP("WATERSLEEP")
static const efftype_id effect_nausea("nausea")
static const efftype_id effect_rat("rat")
static void eff_fun_frostbite(player &u, effect &it)
static void eff_fun_onfire(player &u, effect &it)
static const efftype_id effect_lying_down("lying_down")
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static void eff_fun_rat(player &u, effect &it)
static const efftype_id effect_mutating("mutating")
static void eff_fun_hallu(player &u, effect &it)
static const efftype_id effect_formication("formication")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")
static const efftype_id effect_grabbed("grabbed")
static const efftype_id effect_disabled("disabled")
static const efftype_id effect_alarm_clock("alarm_clock")
static const trait_id trait_NOPAIN("NOPAIN")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const efftype_id effect_brainworms("brainworms")
static const efftype_id effect_onfire("onfire")
static const efftype_id effect_frostbite("frostbite")
bool one_turn_in(const time_duration &duration)
Definition: rng.cpp:70
mtype_id name
Definition: mongroup.h:53

References _, activity, sounds::activity, Creature::add_effect(), add_miss_reason(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_EVIL, AEP_SCHIZO, sounds::alarm, alert, all_body_parts, apply_damage(), Creature::as_player(), bio_watch, body_part_name(), body_part_name_accusative(), BODYTEMP_FREEZING, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_torso, convert_bp(), detail::count(), crossed_threshold(), dermatik_eggs_hatch, anonymous_namespace{iexamine_elevator.cpp}::elevator::dest(), dies_from_asthma_attack, dies_from_drug_overdose, dies_of_infection, Creature::disp_name(), eff_fun_bleed(), eff_fun_bloated(), eff_fun_cold(), eff_fun_frostbite(), eff_fun_fungus(), eff_fun_hallu(), eff_fun_hot(), eff_fun_mutating(), eff_fun_onfire(), eff_fun_rat(), eff_fun_spores(), eff_fun_toxin_buildup(), effect_adrenaline, effect_alarm_clock, effect_antibiotic, effect_asthma, effect_attention, effect_bite, effect_bleed, effect_blind, effect_bloated, effect_bloodworms, effect_boomered, effect_brainworms, effect_cold, effect_datura, effect_dazed, effect_dermatik, effect_disabled, effect_downed, effect_evil, effect_fearparalyze, effect_formication, effect_frostbite, effect_fungus, effect_grabbed, effect_grabbing, effect_hallu, effect_hot, effect_infected, effect_lying_down, effect_mutating, effect_narcosis, effect_nausea, effect_onfire, effect_paincysts, effect_panacea, effect_rat, effect_recover, effect_sleep, effect_slept_through_alarm, effect_spores, effect_strong_antibiotic, effect_tapeworm, effect_teleglow, effect_toxin_buildup, effect_visuals, effect_weak_antibiotic, f_rubble_rock, fall_asleep(), fd_tindalos_rift, focus_pool, ma_buff::from_effect(), g, effect::get_bp(), effect::get_duration(), Creature::get_effect_dur(), get_fatigue(), monster::get_grab_strength(), get_healthy(), get_highest_category(), effect::get_id(), get_int(), effect::get_intensity(), Creature::get_num_blocks_bonus(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), dreams::get_random_for_category(), get_sleep_deprivation(), get_speed(), get_stim(), get_stored_kcal(), get_thirst(), get_weather(), getID(), MonsterGroupManager::GetResultFromGroup(), GROUP_NETHER, harmless, has_active_mutation(), has_alarm_clock(), has_artifact_with(), has_bionic(), Creature::has_effect(), item::has_effect_when_carried(), item::has_effect_when_wielded(), has_psy_protection(), has_trait(), healall(), hostile_spotted_far, hurtall(), id, in_sleep_state(), inp_mngr, irradiate(), Creature::is_avatar(), is_blind(), Creature::is_npc(), Creature::is_player(), light, m_bad, m_good, m_info, m_warning, max_stored_kcal(), mod_dex_bonus(), effect::mod_duration(), mod_fatigue(), mod_healthy_mod(), mod_int_bonus(), effect::mod_intensity(), mod_pain(), mod_per_bonus(), mod_stim(), mod_stored_kcal(), mod_stored_nutr(), mod_str_bonus(), mod_thirst(), mon_dermatik_larva, MORALE_FEELING_BAD, Creature::moves, mutate(), mutate_category(), mutation_category_level, name, MonsterGroupResult::name, num_bp, calendar::once_every(), one_in(), one_turn_in(), pos(), posx(), posy(), posz(), primary_weapon(), input_manager::pump_events(), snippet_library::random_from_category(), Creature::remove_effect(), rng(), character_funcs::roll_can_sleep(), effect::set_duration(), set_fatigue(), Creature::set_moves(), Creature::set_num_blocks_bonus(), Creature::set_part_hp_cur(), player_activity::set_to_null(), SNIPPET, sounds::sound(), sound_hallu(), spores(), str_max, teleglow_teleports, teleport::teleport(), temp_cur, body_part_type::token, trait_CHLOROMORPH, trait_HEAVYSLEEPER2, trait_HIBERNATE, trait_INFRESIST, trait_M_IMMUNE, trait_M_SKIN3, trait_NOPAIN, trait_SCHIZOPHRENIC, trait_SEESLEEP, trait_THRESH_MYCUS, trait_WATERSLEEP, turgid, vomit(), character_effects::vomit_mod(), wake_up(), worn, and x_in_y().

Referenced by process_one_effect().

◆ has_active_bionic()

bool Character::has_active_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id and it is powered on.

Definition at line 1825 of file character.cpp.

1826{
1827 for( const bionic &i : *my_bionics ) {
1828 if( i.id == b ) {
1829 return ( i.powered && i.incapacitated_time == 0_turns );
1830 }
1831 }
1832 return false;
1833}

References b, and my_bionics.

Referenced by absorb_hit(), activate_bionic(), active_light(), adjust_for_focus(), attack_cost(), basic_symbol_color(), burn_move_stamina(), character_martial_arts::can_arm_block(), can_feed_furnace_with(), character_martial_arts::can_leg_block(), comestible_inventory_preset::comestible_inventory_preset(), crit_chance(), avatar::do_read(), do_skill_rust(), game::do_turn(), draw_bionics_titlebar(), draw_skills_tab(), iuse::ehandcuffs(), npc::finish_read(), get_env_resist(), get_hit_weapon(), ranged::gunmode_checks_weapon(), game::handle_action(), has_fire(), has_nv(), hearing_ability(), impact(), in_climate_control(), is_blind(), is_deaf(), is_immune_damage(), is_immune_field(), ma_requirements::is_valid_character(), game::item_action_menu(), trapfunc::ledge(), melee_attack(), melee_special_effects(), modify_morale(), game::monmove(), mut_cbm_encumb(), on_hit(), game::on_move_effects(), perform_technique(), character_martial_arts::pick_style(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), map::player_in_field(), process_items(), character_funcs::rate_sleep_spot(), recalc_sight_limits(), npc::recharge_cbm(), game::remoteveh(), reset_stats(), mattack::riotbot(), roll_bash_damage(), character_funcs::roll_can_sleep(), roll_cut_damage(), roll_stab_damage(), run_cost(), character_funcs::search_surroundings(), sees_with_specials(), game::setremoteveh(), iuse::solarpack(), ranged::throw_item(), throw_range(), avatar_funcs::try_to_sleep(), character_funcs::try_uncanny_dodge(), update_health(), update_needs(), update_stamina(), use_charges(), use_fire(), and npc::wants_to_recharge_cbm().

◆ has_active_item()

bool Character::has_active_item ( const itype_id id) const

Whether the player carries an active item of the given item type.

Definition at line 2510 of file character.cpp.

2511{
2512 return has_item_with( [id]( const item & it ) {
2513 return it.active && it.typeId() == id;
2514 } );
2515}

References item::active, visitable< Character >::has_item_with(), and item::typeId().

Referenced by deactivate_bionic(), game::handle_action(), iuse::mp3(), game::remoteveh(), and game::setremoteveh().

◆ has_active_mutation()

◆ has_activity() [1/2]

bool Character::has_activity ( const activity_id type) const

◆ has_activity() [2/2]

bool Character::has_activity ( const std::vector< activity_id > &  types) const

Check if player currently has any of the given activities.

Definition at line 9234 of file character.cpp.

9235{
9236 return std::find( types.begin(), types.end(), activity.id() ) != types.end();
9237}
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)

References activity, detail::find(), and player_activity::id().

◆ has_addiction()

bool Character::has_addiction ( add_type  type) const

Returns true if the player has an addiction of the specified type.

Definition at line 1892 of file suffer.cpp.

1893{
1894 return std::any_of( addictions.begin(), addictions.end(),
1895 [type]( const addiction & ad ) {
1896 return ad.type == type && ad.intensity >= MIN_ADDICTION_LEVEL;
1897 } );
1898}

References addictions, and type.

Referenced by character_funcs::rate_sleep_spot().

◆ has_alarm_clock()

bool Character::has_alarm_clock ( ) const

Returns true if the player or their vehicle has an alarm clock.

Definition at line 722 of file character.cpp.

723{
724 map &here = get_map();
725 return ( has_item_with_flag( "ALARMCLOCK", true ) ||
726 ( here.veh_at( pos() ) &&
727 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "ALARMCLOCK" ) ) ) ||
729}
static const bionic_id bio_watch("bio_watch")
bool has_item_with_flag(const std::string &flag, bool need_charges=false) const
Definition: character.cpp:9591

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), pos(), and vehicle.

Referenced by hardcoded_effects(), sleep(), and wait().

◆ has_any_bionic()

bool Character::has_any_bionic ( ) const

Returns true if the player has any bionic.

Definition at line 1835 of file character.cpp.

1836{
1837 return !get_bionics().empty();
1838}

References get_bionics().

Referenced by mattack::nurse_operate().

◆ has_artifact_with()

bool Character::has_artifact_with ( art_effect_passive  effect) const
virtual

Reimplemented in npc.

Definition at line 3213 of file character.cpp.

3214{
3215 for( const item *weapon : wielded_items() ) {
3216 if( weapon->has_effect_when_wielded( effect ) ) {
3217 return true;
3218 }
3219 }
3220 for( auto &i : worn ) {
3221 if( i.has_effect_when_worn( effect ) ) {
3222 return true;
3223 }
3224 }
3225 return has_item_with( [effect]( const item & it ) {
3226 return it.has_effect_when_carried( effect );
3227 } );
3228}
std::vector< item * > wielded_items()
Returns all equipped items that require a limb to be held.
Definition: melee.cpp:186

References item::has_effect_when_carried(), visitable< Character >::has_item_with(), wielded_items(), and worn.

Referenced by active_light(), basic_symbol_color(), deal_damage(), item::food_info(), hardcoded_effects(), is_immune_damage(), is_invisible(), melee_attack(), map::open_door(), recalc_sight_limits(), recalc_speed_bonus(), suffer_from_artifacts(), suffer_while_awake(), update_health(), game::walk_move(), and weight_capacity().

◆ has_base_trait()

bool Character::has_base_trait ( const trait_id b) const

Returns true if the player has the entered starting trait.

Definition at line 119 of file mutation.cpp.

120{
121 // Look only at base traits
122 return my_traits.find( b ) != my_traits.end();
123}

References b, and my_traits.

Referenced by build_mut_dependency_map(), do_purify(), wish_mutate_callback::key(), mutate_towards(), old_mutate(), iuse::purify_iv(), iuse::purify_smart(), remove_mutation(), detail::show_mutations_ui_internal(), and debug_menu::wishmutate().

◆ has_bionic()

bool Character::has_bionic ( const bionic_id b) const

Returns true if the player has the entered bionic id.

Definition at line 1815 of file character.cpp.

1816{
1817 for( const bionic_id &bid : get_bionics() ) {
1818 if( bid == b ) {
1819 return true;
1820 }
1821 }
1822 return false;
1823}

References b, and get_bionics().

Referenced by npc::activate_bionic_by_id(), add_bionic(), iexamine::autodoc(), autodoc_internal(), bionics_install_failure(), talk_trial::calc_chance(), calc_needs_rates(), character_martial_arts::can_arm_block(), character_martial_arts::can_leg_block(), npc::can_read(), can_uninstall_bionic(), install_bionic_actor::can_use(), item::color_in_inventory(), consume_effects(), consume_med(), activity_handlers::cracking_do_turn(), deactivate_bionic(), npc::deactivate_bionic_by_id(), draw_env_compact(), draw_speed_tab(), draw_time_classic(), eat(), iuse::einktabletpc(), iexamine::fireplace(), item::food_info(), avatar::get_book_reader(), bionic_install_preset::get_denial(), bionic_install_surgeon_preset::get_denial(), get_temp(), ranged::get_weapon_dispersion(), hardcoded_effects(), has_alarm_clock(), has_enough_anesth(), has_fire(), has_watch(), is_immune_effect(), player::load(), game::on_move_effects(), activity_handlers::operation_do_turn(), overmap_sight_range(), iexamine::pay_gas(), sounds::process_sound_markers(), read_speed(), recalc_sight_limits(), recalc_speed_bonus(), iuse::robotcontrol(), roll_cut_damage(), roll_stab_damage(), run_cost(), iexamine::safe(), conditional_t< T >::set_has_bionics(), sight_impaired(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_from_sunburn(), suffer_while_underwater(), try_start_hacking(), update_bodytemp(), consume_drug_iuse::use(), npc::use_bionic_by_id(), game::use_computer(), use_fire(), volume_capacity_reduced_by(), avatar::wake_up(), game::walk_move(), and will_eat().

◆ has_bionics()

bool Character::has_bionics ( ) const

Whether character has any bionics installed.

Definition at line 2671 of file bionics.cpp.

2672{
2673 return !my_bionics->empty() || has_max_power();
2674}

References has_max_power(), and my_bionics.

Referenced by conditional_t< T >::set_has_bionics().

◆ has_charges()

bool Character::has_charges ( const itype_id it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
) const

Definition at line 9608 of file character.cpp.

9610{
9611 if( it == itype_fire || it == itype_apparatus ) {
9612 return has_fire( quantity );
9613 }
9614 if( it == itype_UPS && is_mounted() &&
9615 mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) ) {
9616 auto mons = mounted_creature.get();
9617 return quantity <= mons->battery_item->ammo_remaining();
9618 }
9619 if( it == itype_bio_armor ) {
9620 int mod_qty = 0;
9621 float efficiency = 1;
9622 for( const bionic &bio : *my_bionics ) {
9623 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9624 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9625 }
9626 }
9627 if( efficiency == 1 ) {
9628 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9629 }
9630 mod_qty = quantity / efficiency;
9631 return ( has_power() && get_power_level() >= units::from_kilojoule( mod_qty ) );
9632 }
9633 return charges_of( it, quantity, filter ) == quantity;
9634}
static const itype_id itype_fire("fire")
static const flag_str_id flag_BIONIC_ARMOR_INTERFACE("BIONIC_ARMOR_INTERFACE")
static const itype_id itype_apparatus("apparatus")
bool has_power() const
Definition: character.cpp:1947
bool has_fire(int quantity) const
Definition: character.cpp:9755

References visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, units::from_kilojoule(), get_power_level(), has_fire(), has_power(), is_mounted(), itype_apparatus, itype_bio_armor, itype_fire, itype_UPS, MF_RIDEABLE_MECH, mounted_creature, and my_bionics.

Referenced by iexamine::arcfurnace_empty(), iuse::cable_attach(), can_eat(), iexamine::can_fertilize(), can_reload(), cauterize_actor::can_use(), craft_command::check_item_components_missing(), craft_command::check_tool_components_missing(), consume_charges(), consume_med(), consume_remote_fuel(), player::craft_consume_tools(), iuse::ecig(), activity_handlers::fertilize_plot_do_turn(), find_remote_fuel(), crafting::find_tool_component(), iuse::firecracker_pack(), avatar_funcs::gunmod_add(), ranged::gunmode_checks_weapon(), has_enough_charges(), has_fire(), npc::heal_self(), iexamine::kiln_empty(), npc::move(), iexamine::pay_gas(), avatar_action::reload(), talk_effect_fun_t::set_consume_item(), conditional_t< T >::set_has_items(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), iuse::smoking(), suffer_from_asthma(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), use_charges_if_avail(), and use_fire().

◆ has_child_flag()

bool Character::has_child_flag ( const trait_id flag) const

Returns true if the player has the entered mutation child flag.

Definition at line 1460 of file mutation.cpp.

1461{
1462 for( const trait_id &elem : flag->replacements ) {
1463 const trait_id &tmp = elem;
1464 if( has_trait( tmp ) || has_child_flag( tmp ) ) {
1465 return true;
1466 }
1467 }
1468 return false;
1469}
bool has_child_flag(const trait_id &flag) const
Returns true if the player has the entered mutation child flag.
Definition: mutation.cpp:1460

References has_child_flag(), has_trait(), and mutation_branch::replacements.

Referenced by has_child_flag(), mutate_towards(), mutation_ok(), and remove_child_flag().

◆ has_destination()

◆ has_destination_activity()

bool Character::has_destination_activity ( ) const

Definition at line 10522 of file character.cpp.

10523{
10526}
player_activity get_destination_activity() const
Definition: character.cpp:963
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8417
bool is_null() const

References destination_point, get_destination_activity(), get_map(), map::getlocal(), player_activity::is_null(), and position.

Referenced by game::handle_action(), npc::move(), npc::move_to(), and start_destination_activity().

◆ has_distant_destination()

bool Character::has_distant_destination ( ) const

Definition at line 10506 of file character.cpp.

10507{
10510}
static const activity_id ACT_TRAVELLING("ACT_TRAVELLING")
std::vector< tripoint_abs_omt > omt_path
Route for overmap scale traveling.
Definition: character.h:1837

References ACT_TRAVELLING, get_destination_activity(), has_destination(), player_activity::id(), player_activity::is_null(), and omt_path.

Referenced by game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), and game::do_turn().

◆ has_enough_anesth()

bool Character::has_enough_anesth ( const itype cbm,
player patient 
)

Has enough anesthetic for surgery.

Definition at line 1878 of file bionics.cpp.

1879{
1880 if( !cbm->bionic ) {
1881 debugmsg( "has_enough_anesth( const itype *cbm ): %s is not a bionic", cbm->get_id() );
1882 return false;
1883 }
1884
1887 return true;
1888 }
1889
1890 const int weight = 7;
1891 const requirement_data req_anesth = *requirement_id( "anesthetic" ) *
1892 cbm->bionic->difficulty * 2 * weight;
1893
1895}
static const bionic_id bio_painkiller("bio_painkiller")
static const trait_id trait_DEBUG_BIONICS("DEBUG_BIONICS")
static const trait_id trait_NOPAIN("NOPAIN")
bool is_crafting_component(const item &component)
Default filter for crafting component searches.
Definition: item.h:2275
cata::value_ptr< islot_bionic > bionic
Definition: itype.h:834
bool can_make_with_inventory(const inventory &crafting_inv, const std::function< bool(const item &)> &filter, int batch=1, cost_adjustment=cost_adjustment::none) const
Returns true if the requirements are fufilled by the filtered inventory.
string_id< requirement_data > requirement_id
Definition: type_id.h:146

References bio_painkiller, itype::bionic, requirement_data::can_make_with_inventory(), crafting_inventory(), debugmsg, itype::get_id(), has_bionic(), has_trait(), is_crafting_component(), trait_DEBUG_BIONICS, and trait_NOPAIN.

Referenced by bionic_install_preset::get_denial(), and bionic_uninstall_preset::get_denial().

◆ has_enough_charges()

bool Character::has_enough_charges ( const item it,
bool  show_msg 
) const

Has the item enough charges to invoke its use function? Also checks if UPS from this player is used instead of item charges.

Definition at line 7365 of file character.cpp.

7366{
7367 if( !it.is_tool() || !it.ammo_required() ) {
7368 return true;
7369 }
7370 if( it.is_power_armor() ) {
7371 if( ( character_funcs::can_interface_armor( *this ) &&
7374 it.ammo_sufficient() ) {
7375 return true;
7376 }
7377
7378 if( show_msg ) {
7379 if( it.has_flag( flag_USE_UPS ) ) {
7381 vgettext( "Your %s needs %d charge, from some UPS or a Bionic Power Interface.",
7382 "Your %s needs %d charges, from some UPS or a Bionic Power Interface.",
7383 it.ammo_required() ),
7384 it.tname(), it.ammo_required() );
7385 } else {
7387 vgettext( "Your %s needs %d charge, from a Bionic Power Interface.",
7388 "Your %s needs %d charges, from a Bionic Power Interface.",
7389 it.ammo_required() ),
7390 it.tname(), it.ammo_required() );
7391 }
7392 }
7393 return false;
7394 }
7395 if( it.has_flag( flag_USE_UPS ) ) {
7396 if( has_charges( itype_UPS, it.ammo_required() ) || it.ammo_sufficient() ) {
7397 return true;
7398 }
7399 if( show_msg ) {
7401 vgettext( "Your %s needs %d charge from some UPS.",
7402 "Your %s needs %d charges from some UPS.",
7403 it.ammo_required() ),
7404 it.tname(), it.ammo_required() );
7405 }
7406 return false;
7407 } else if( !it.ammo_sufficient() ) {
7408 if( show_msg ) {
7410 vgettext( "Your %s has %d charge but needs %d.",
7411 "Your %s has %d charges but needs %d.",
7412 it.ammo_remaining() ),
7413 it.tname(), it.ammo_remaining(), it.ammo_required() );
7414 }
7415 return false;
7416 }
7417 return true;
7418}
bool ammo_sufficient(int qty=1) const
Check if sufficient ammo is loaded for given number of uses.
Definition: item.cpp:7477

References Creature::add_msg_if_player(), item::ammo_remaining(), item::ammo_required(), item::ammo_sufficient(), character_funcs::can_interface_armor(), flag_USE_UPS(), has_charges(), item::has_flag(), item::is_power_armor(), item::is_tool(), itype_bio_armor, itype_UPS, m_info, item::tname(), and vgettext().

Referenced by activatable_inventory_preset::get_denial(), invoke_item(), iuse::jackhammer(), and iuse::note_bionics().

◆ has_fire()

bool Character::has_fire ( int  quantity) const

Definition at line 9755 of file character.cpp.

9756{
9757 // TODO: Replace this with a "tool produces fire" flag.
9758
9759 if( get_map().has_nearby_fire( pos() ) ) {
9760 return true;
9761 } else if( has_item_with_flag( "FIRE" ) ) {
9762 return true;
9763 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9764 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9765 for( auto &i : firestarters ) {
9766 if( !i->type->can_have_charges() ) {
9767 const use_function *usef = i->type->get_use( "firestarter" );
9768 if( !usef ) {
9769 debugmsg( "failed to get use func 'firestarter' for item '%s'", i->typeId().c_str() );
9770 continue;
9771 }
9772 const firestarter_actor *actor = dynamic_cast<const firestarter_actor *>( usef->get_actor_ptr() );
9773 if( actor->can_use( *this->as_character(), *i, false, tripoint_zero ).success() ) {
9774 return true;
9775 }
9776 } else if( has_charges( i->typeId(), quantity ) ) {
9777 return true;
9778 }
9779 }
9780 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9781 return true;
9782 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9783 return true;
9784 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9785 return true;
9786 } else if( is_npc() ) {
9787 // HACK: A hack to make NPCs use their Molotovs
9788 return true;
9789 }
9790 return false;
9791}
static const bionic_id bio_lighter("bio_lighter")
static const bionic_id bio_laser("bio_laser")
static const bionic_id bio_tools("bio_tools")
std::vector< const item * > all_items_with_flag(const std::string &flag) const
All items that have the given flag (item::has_flag).
Definition: character.cpp:9601
Starts a fire instantly.
Definition: iuse_actor.h:529
ret_val< bool > can_use(const Character &, const item &, bool, const tripoint &) const override
iuse_actor * get_actor_ptr()
Definition: iuse.h:316

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, firestarter_actor::can_use(), debugmsg, use_function::get_actor_ptr(), get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), Creature::is_npc(), pos(), and tripoint_zero.

Referenced by has_charges(), and symbol_color().

◆ has_grab_break_tec()

bool Character::has_grab_break_tec ( ) const
overridevirtual

Returns true if the player has a grab breaking technique available.

Implements Creature.

Definition at line 1242 of file martialarts.cpp.

1243{
1244 return martial_arts_data->has_grab_break_tec();
1245}

References martial_arts_data.

Referenced by can_use_grab_break_tec(), deal_damage(), and mattack::grab().

◆ has_item_with_flag()

bool Character::has_item_with_flag ( const std::string &  flag,
bool  need_charges = false 
) const

Definition at line 9591 of file character.cpp.

9592{
9593 return has_item_with( [&flag, &need_charges]( const item & it ) {
9594 if( it.is_tool() && need_charges ) {
9595 return it.has_flag( flag ) && it.type->tool->max_charges ? it.charges > 0 : it.has_flag( flag );
9596 }
9597 return it.has_flag( flag );
9598 } );
9599}

References item::has_flag(), visitable< Character >::has_item_with(), and item::is_tool().

Referenced by draw_env_compact(), draw_time_classic(), npc::faction_display(), get_temp(), has_alarm_clock(), has_fire(), has_watch(), loot(), overmap_sight_range(), monexamine::pet_menu(), npc::reach_omt_destination(), and use_fire().

◆ has_mabuff()

bool Character::has_mabuff ( const mabuff_id buff_id) const

Returns true if the player has any martial arts buffs attached.

Definition at line 1235 of file martialarts.cpp.

1236{
1237 return search_ma_buff_effect( *effects, [&id]( const ma_buff & b, const effect & ) {
1238 return b.id == id;
1239 } );
1240}
static bool search_ma_buff_effect(const C &container, F f)

References b, Creature::effects, id, and search_ma_buff_effect().

Referenced by ma_requirements::is_valid_character().

◆ has_max_power()

bool Character::has_max_power ( ) const

Definition at line 1952 of file character.cpp.

1953{
1954 return max_power_level > 0_kJ;
1955}

References max_power_level.

Referenced by bionics_install_failure(), has_bionics(), power_stat(), and suffer_from_bad_bionics().

◆ has_mission_item()

bool Character::has_mission_item ( int  mission_id) const

Definition at line 2525 of file character.cpp.

2526{
2527 return mission_id != -1 && has_item_with( has_mission_item_filter{ mission_id } );
2528}

References visitable< Character >::has_item_with().

◆ has_morale()

bool Character::has_morale ( const morale_type type) const

Definition at line 9109 of file character.cpp.

9110{
9111 return morale->has( type );
9112}

References morale, and type.

Referenced by ranged::fire_gun(), suffer_from_other_mutations(), and iuse::towel_common().

◆ has_morale_to_craft()

bool Character::has_morale_to_craft ( ) const

Definition at line 337 of file crafting.cpp.

338{
339 return get_morale_level() >= -50;
340}
int get_morale_level() const
Definition: character.cpp:9093

References get_morale_level().

Referenced by game::butcher(), veh_interact::cant_do(), and iuse::multicooker().

◆ has_morale_to_read()

bool Character::has_morale_to_read ( ) const

Definition at line 9129 of file character.cpp.

9130{
9131 return get_morale_level() >= -40;
9132}

References get_morale_level().

Referenced by avatar::get_book_reader().

◆ has_nv()

bool Character::has_nv ( )

Returns true if the player has some form of night vision.

Definition at line 3653 of file character.cpp.

3654{
3655 static bool nv = false;
3656
3657 if( !nv_cached ) {
3658 nv_cached = true;
3659 nv = ( worn_with_flag( flag_GNV_EFFECT ) ||
3662 }
3663
3664 return nv;
3665}
static const std::string flag_GNV_EFFECT("GNV_EFFECT")
static const std::string flag_EFFECT_NIGHT_VISION("EFFECT_NIGHT_VISION")
static const bionic_id bio_night_vision("bio_night_vision")

References bio_night_vision, flag_EFFECT_NIGHT_VISION(), flag_GNV_EFFECT(), has_active_bionic(), Creature::has_effect_with_flag(), nv_cached, and worn_with_flag().

Referenced by recalc_sight_limits().

◆ has_opposite_trait()

bool Character::has_opposite_trait ( const trait_id flag) const

Returns true if character has a trait which cancels the entered trait.

Definition at line 9926 of file character.cpp.

9927{
9928 for( const trait_id &i : flag->cancels ) {
9929 if( has_trait( i ) ) {
9930 return true;
9931 }
9932 }
9933 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
9934 for( const trait_id &canceled_trait : mut.first->cancels ) {
9935 if( canceled_trait == flag ) {
9936 return true;
9937 }
9938 }
9939 }
9940 return false;
9941}
std::vector< trait_id > cancels
Definition: mutation.h:264

References mutation_branch::cancels, has_trait(), and my_mutations.

Referenced by known_magic::can_learn_spell(), and newcharacter::has_conflicting_trait().

◆ has_power()

bool Character::has_power ( ) const

◆ has_stashed_activity()

bool Character::has_stashed_activity ( ) const

Definition at line 919 of file character.cpp.

920{
921 return static_cast<bool>( stashed_outbounds_activity );
922}

References stashed_outbounds_activity.

Referenced by npc::move().

◆ has_trait()

bool Character::has_trait ( const trait_id b) const
overridevirtual

Returns true if the player has the entered trait.

Reimplemented from Creature.

Definition at line 101 of file mutation.cpp.

102{
103 return my_mutations.count( b ) || enchantment_cache->get_mutations().count( b );
104}

References b, enchantment_cache, and my_mutations.

Referenced by absorb_hit(), activate_mutation(), add_addiction(), add_bionic(), character_funcs::add_pain_msg(), newcharacter::add_traits(), addict_effect(), adjust_for_focus(), alcohol(), allergy_type(), iuse::anticonvulsant(), iuse::antiparasitic(), apply_damage(), apply_persistent_morale(), monster::attitude(), iexamine::autodoc(), autodoc_internal(), iexamine::bars(), character_funcs::base_comfort_value(), basic_symbol_color(), bionics_pl_skill(), iuse::blech(), iuse::blood_draw(), bloodType(), activity_handlers::build_do_turn(), burn_move_stamina(), calc_all_parts_hp(), talk_trial::calc_chance(), character_effects::calc_focus_equilibrium(), calc_needs_rates(), player::can_continue_craft(), can_eat(), can_install_bionics(), spell::can_learn(), can_pick_weight(), veh_interact::can_potentially_install(), npc::can_read(), veh_interact::can_remove_part(), cauterize_actor::can_use(), install_bionic_actor::can_use(), can_wear(), veh_interact::cant_do(), cauterize_actor::cauterize_effect(), iexamine::chainfence(), game::chat(), check_needs_extremes(), game::check_safe_mode_allowed(), game::cleanup_at_end(), item::color_in_inventory(), talk_function::commune_farmfield(), talk_function::companion_mission(), veh_interact::complete_vehicle(), construction_color(), consume_effects(), consume_item(), player::consume_items(), player::consume_tools(), iuse::contacts(), game::control_vehicle(), cough(), player::craft_consume_tools(), crafting_inventory(), player::crafting_success_roll(), avatar::create(), craft_command::create_in_progress_craft(), iuse::datura(), deal_damage(), debug_vision(), mattack::dermatik(), trap::detect_trap(), monster::die(), character_display::disp_info(), avatar::disp_morale(), veh_interact::do_mend(), do_purify(), game::do_turn(), construct::done_vehicle(), overmap_ui::draw_ascii(), draw_limb_health(), overmap_ui::draw_om_sidebar(), draw_speed_tab(), drench(), eat(), eff_fun_spores(), iuse::einktabletpc(), game::extended_description(), fall_damage_mod(), talk_function::field_harvest(), item::final_info(), game::find_or_make_stairs(), character_funcs::fine_detail_vision_mod(), npc::finish_read(), ranged::fire_gun(), floor_warmth(), iexamine::flower_dahlia(), item::food_info(), talk_function::forage_return(), npc::form_opinion(), fun_for(), fungal_effects::fungalize(), dialogue::gen_responses(), character_funcs::get_book_fun_for(), avatar::get_book_reader(), bionic_install_preset::get_denial(), get_dodge(), get_env_resist(), get_face_type(), get_hunger_description(), character_funcs::get_lift_strength(), get_miss_reason(), npc::get_monster_faction(), overmap_ui::get_overmap_neighbors(), get_pain_description(), character_effects::get_pain_penalty(), get_shout_volume(), give_item_to(), avatar_funcs::gunmod_add(), avatar_funcs::gunmod_installation_odds(), game::handle_action(), hardcoded_effects(), hardcoded_mutation_attack(), iexamine::harvest_plant(), has_child_flag(), has_enough_anesth(), newcharacter::has_higher_trait(), newcharacter::has_lower_trait(), has_opposite_trait(), newcharacter::has_same_type_trait(), hearing_ability(), hit_roll(), hurtall(), in_climate_control(), install_bionics(), introduce_into_anesthesia(), irradiate(), character_funcs::is_bp_immune_to(), is_deaf(), item::is_filthy(), character_funcs::is_fun_to_read(), is_immune_damage(), is_immune_effect(), is_immune_field(), is_invisible(), wish_mutate_callback::key(), game::knockback(), talk_function::labor_return(), known_magic::learn_spell(), trapfunc::ledge(), iexamine::ledge(), player::load(), marloss_common(), marloss_prevented(), iuse::meditate(), melee_attack(), avatar_funcs::mend_item(), iuse::meth(), mod_pain(), modify_morale(), modify_stimulation(), game::mon_info_update(), avatar_action::move(), iuse::multicooker(), mutate(), mutate_category(), mutate_towards(), mutation_chances(), mutation_ok(), iuse::mycus(), old_mutate(), on_hit(), on_hurt(), npc::on_load(), map::open_door(), iexamine::pay_gas(), perform_install(), petfood(), pick_part_to_heal(), activity_handlers::pickaxe_finish(), trapfunc::pit(), trapfunc::pit_glass(), trapfunc::pit_spikes(), game::place_player(), iuse::plantblech(), player_can_build(), player_can_see_to_build(), map::player_in_field(), iuse::poison(), iuse::portable_game(), practice(), print_health(), game::print_terrain_info(), process_effects_internal(), item::process_litcig(), process_one_effect(), sounds::process_sound_markers(), process_turn(), iuse::purify_iv(), iuse::purify_smart(), avatar::randomize(), npc::randomize(), character_funcs::rate_sleep_spot(), react_to_felt_pain(), avatar::read(), recalc_sight_limits(), recalc_speed_bonus(), wish_mutate_callback::refresh(), remove_child_flag(), remove_mutation(), reset_stats(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), talk_trial::roll(), roll_bash_damage(), rooted(), rooted_message(), iexamine::rubble(), run_cost(), npc::say(), talk_function::scavenging_patrol_return(), sees_with_specials(), player::select_item_component(), conditional_t< T >::set_has_any_trait(), conditional_t< T >::set_has_trait(), set_traits(), shout(), iexamine::shrub_marloss(), sight_impaired(), iexamine::sign(), trapfunc::sinkhole(), game::slip_down(), game::start_game(), stumble(), suffer(), suffer_from_addictions(), suffer_from_chemimbalance(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_sunburn(), suffer_in_sunlight(), suffer_while_awake(), suffer_while_underwater(), swim_speed(), npc::talk_to_u(), test_crossing_threshold(), npc::time_to_read(), avatar::time_to_read(), avatar_funcs::toolmod_add(), iexamine::trap(), activity_handlers::tree_communion_do_turn(), iexamine::tree_marloss(), try_reject_mutagen(), try_start_hacking(), avatar_funcs::try_steal_from_npc(), avatar_funcs::try_to_sleep(), uninstall_bionic(), update_body(), character_funcs::update_body_wetness(), update_bodytemp(), update_needs(), veh_interact::update_part_requirements(), game::update_stair_monsters(), update_stomach(), consume_drug_iuse::use(), cauterize_actor::use(), enzlave_actor::use(), mutagen_actor::use(), mutagen_iv_actor::use(), game::use_computer(), game::vertical_move(), iuse::vibe(), volume_capacity_reduced_by(), character_effects::vomit_mod(), game::walk_move(), iuse::weed_cake(), weed_msg(), weight_capacity(), weather_effect::wet_player(), will_eat(), and debug_menu::wishmutate().

◆ has_trait_flag()

bool Character::has_trait_flag ( const std::string &  b) const

Returns true if player has a trait with a flag.

Definition at line 106 of file mutation.cpp.

107{
108 // UGLY, SLOW, should be cached as my_mutation_flags or something
109 for( const trait_id &mut : get_mutations() ) {
110 const mutation_branch &mut_data = mut.obj();
111 if( mut_data.flags.count( b ) > 0 ) {
112 return true;
113 }
114 }
115
116 return false;
117}
std::set< std::string > flags
Definition: mutation.h:268

References b, mutation_branch::flags, and get_mutations().

Referenced by consider_butchery(), do_skill_rust(), item::food_info(), mod_rad(), mod_thirst(), practice(), conditional_t< T >::set_has_trait_flag(), spell::spell_fail(), enzlave_actor::use(), and will_eat().

◆ has_two_arms()

bool Character::has_two_arms ( ) const

Returns true if the player has two functioning arms.

Returns true if the character has two functioning arms.

Definition at line 1220 of file character.cpp.

1221{
1222 return get_working_arm_count() >= 2;
1223}

References get_working_arm_count().

Referenced by can_wear(), can_wield(), ranged::gunmode_checks_common(), hardcoded_mutation_attack(), map::player_in_field(), and mattack::riotbot().

◆ has_watch()

bool Character::has_watch ( ) const

Returns true if the player or their vehicle has a watch.

Definition at line 731 of file character.cpp.

732{
733 map &here = get_map();
734 return ( has_item_with_flag( "WATCH", true ) ||
735 ( here.veh_at( pos() ) &&
736 !empty( here.veh_at( pos() )->vehicle().get_avail_parts( "WATCH" ) ) ) ||
738}

References bio_watch, get_map(), has_bionic(), has_item_with_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), pos(), and vehicle.

Referenced by draw_loc_labels(), draw_time(), draw_time_classic(), game::list_missions(), and wait().

◆ has_weapon()

bool Character::has_weapon ( ) const
overridevirtual

Implements Creature.

Definition at line 10376 of file character.cpp.

10377{
10378 return !unarmed_attack();
10379}
bool unarmed_attack() const
True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.
Definition: melee.cpp:211

References unarmed_attack().

Referenced by perform_technique(), pick_technique(), and npc::talk_to_u().

◆ head_cloth_encumbrance()

int Character::head_cloth_encumbrance ( ) const

Returns the total encumbrance of all SKINTIGHT and HELMET_COMPAT items coveringi the head.

Definition at line 8917 of file character.cpp.

8918{
8919 int ret = 0;
8920 for( auto &i : worn ) {
8921 const item *worn_item = &i;
8922 if( i.covers( bp_head ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8923 ( worn_item->has_flag( flag_HELMET_COMPAT ) || worn_item->has_flag( flag_SKINTIGHT ) ) ) {
8924 ret += worn_item->get_encumber( *this );
8925 }
8926 }
8927 return ret;
8928}

References bp_head, flag_HELMET_COMPAT(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), item::get_encumber(), item::has_flag(), cata::hash64_detail::ret, and worn.

Referenced by can_wear().

◆ heal()

void Character::heal ( const bodypart_id healed,
int  dam 
)

Heals a body_part for dam.

Definition at line 8648 of file character.cpp.

8649{
8650 const int max_hp = get_part_hp_max( healed );
8651 const int cur_hp = get_part_hp_cur( healed );
8652 const int effective_heal = std::min( dam, max_hp - cur_hp );
8653 mod_part_hp_cur( healed, effective_heal );
8654 g->events().send<event_type::character_heals_damage>( getID(), effective_heal );
8655 if( cur_hp + dam >= max_hp ) {
8656 remove_effect( effect_disabled, healed.id() );
8657 }
8658}
static const efftype_id effect_disabled("disabled")
@ character_heals_damage

References character_heals_damage, effect_disabled, g, Creature::get_part_hp_cur(), Creature::get_part_hp_max(), getID(), int_id< T >::id(), Creature::mod_part_hp_cur(), and Creature::remove_effect().

Referenced by iexamine::autodoc(), enforce_minimum_healing(), heal_actor::finish_using(), give_aid_to(), healall(), process_bionic(), regen(), and suffer_water_damage().

◆ healall()

void Character::healall ( int  dam)

Heals all body parts for dam.

Definition at line 8660 of file character.cpp.

8661{
8662 for( const bodypart_id &bp : get_all_body_parts() ) {
8663 heal( bp, dam );
8664 mod_part_healed_total( bp, dam );
8665 }
8666}
void mod_part_healed_total(const bodypart_id &id, int mod)
Definition: creature.cpp:1647

References Creature::get_all_body_parts(), heal(), and Creature::mod_part_healed_total().

Referenced by iuse::artifact(), consume_effects(), hardcoded_effects(), spell::heal(), iuse::jet_injector(), melee_attack(), iuse::mycus(), and suffer_from_radiation().

◆ healed_bp()

void Character::healed_bp ( int  bp,
int  amount 
)

Definition at line 7751 of file character.cpp.

7752{
7753 healed_total[bp] += amount;
7754}

References healed_total.

Referenced by regen().

◆ healing_rate()

float Character::healing_rate ( float  at_rest_quality) const

Average hit points healed per turn.

Definition at line 6663 of file character.cpp.

6664{
6665 // TODO: Cache
6666 float heal_rate;
6667 if( !is_npc() ) {
6668 heal_rate = get_option< float >( "PLAYER_HEALING_RATE" );
6669 } else {
6670 heal_rate = get_option< float >( "NPC_HEALING_RATE" );
6671 }
6672 float awake_rate = heal_rate * mutation_value( "healing_awake" );
6673 float final_rate = 0.0f;
6674 if( awake_rate > 0.0f ) {
6675 final_rate += awake_rate;
6676 } else if( at_rest_quality < 1.0f ) {
6677 // Resting protects from rot
6678 final_rate += ( 1.0f - at_rest_quality ) * awake_rate;
6679 }
6680 float asleep_rate = 0.0f;
6681 if( at_rest_quality > 0.0f ) {
6682 asleep_rate = at_rest_quality * heal_rate * ( 1.0f + mutation_value( "healing_resting" ) );
6683 }
6684 if( asleep_rate > 0.0f ) {
6685 final_rate += asleep_rate * ( 1.0f + get_healthy() / 200.0f );
6686 }
6687
6688 // Most common case: awake player with no regenerative abilities
6689 // ~7e-5 is 1 hp per day, anything less than that is totally negligible
6690 static constexpr float eps = 0.000007f;
6691 add_msg( m_debug, "%s healing: %.6f", name, final_rate );
6692 if( std::abs( final_rate ) < eps ) {
6693 return 0.0f;
6694 }
6695
6696 float primary_hp_mod = mutation_value( "hp_modifier" );
6697 if( primary_hp_mod < 0.0f ) {
6698 // HP mod can't get below -1.0
6699 final_rate *= 1.0f + primary_hp_mod;
6700 }
6701
6702 return final_rate;
6703}

References add_msg(), get_healthy(), Creature::is_npc(), m_debug, mutation_value(), and name.

Referenced by regen().

◆ healing_rate_medicine()

float Character::healing_rate_medicine ( float  at_rest_quality,
const bodypart_id bp 
) const

Average hit points healed per turn from healing effects.

Definition at line 6705 of file character.cpp.

6706{
6707 float rate_medicine = 0.0f;
6708 float bandaged_rate = 0.0f;
6709 float disinfected_rate = 0.0f;
6710
6711 const effect &e_bandaged = get_effect( effect_bandaged, bp->token );
6712 const effect &e_disinfected = get_effect( effect_disinfected, bp->token );
6713
6714 if( !e_bandaged.is_null() ) {
6715 bandaged_rate += static_cast<float>( e_bandaged.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6716 ( 24_hours );
6717 if( bp == bodypart_id( "head" ) ) {
6718 bandaged_rate *= e_bandaged.get_amount( "HEAL_HEAD" ) / 100.0f;
6719 }
6720 if( bp == bodypart_id( "torso" ) ) {
6721 bandaged_rate *= e_bandaged.get_amount( "HEAL_TORSO" ) / 100.0f;
6722 }
6723 }
6724
6725 if( !e_disinfected.is_null() ) {
6726 disinfected_rate += static_cast<float>( e_disinfected.get_amount( "HEAL_RATE" ) ) / to_turns<int>
6727 ( 24_hours );
6728 if( bp == bodypart_id( "head" ) ) {
6729 disinfected_rate *= e_disinfected.get_amount( "HEAL_HEAD" ) / 100.0f;
6730 }
6731 if( bp == bodypart_id( "torso" ) ) {
6732 disinfected_rate *= e_disinfected.get_amount( "HEAL_TORSO" ) / 100.0f;
6733 }
6734 }
6735
6736 rate_medicine += bandaged_rate + disinfected_rate;
6737 rate_medicine *= 1.0f + mutation_value( "healing_resting" );
6738 rate_medicine *= 1.0f + at_rest_quality;
6739
6740 // increase healing if character has both effects
6741 if( !e_bandaged.is_null() && !e_disinfected.is_null() ) {
6742 rate_medicine *= 2;
6743 }
6744
6745 if( get_healthy() > 0.0f ) {
6746 rate_medicine *= 1.0f + get_healthy() / 200.0f;
6747 } else {
6748 rate_medicine *= 1.0f + get_healthy() / 400.0f;
6749 }
6750 float primary_hp_mod = mutation_value( "hp_modifier" );
6751 if( primary_hp_mod < 0.0f ) {
6752 // HP mod can't get below -1.0
6753 rate_medicine *= 1.0f + primary_hp_mod;
6754 }
6755 return rate_medicine;
6756}
bool is_null() const
Returns true if the effect is the result of effect(), ie.
Definition: effect.cpp:553
int get_amount(std::string arg, bool reduced=false) const
Returns the amount of a modifier type applied when a new effect is first added.
Definition: effect.cpp:974

References effect_bandaged, effect_disinfected, effect::get_amount(), Creature::get_effect(), get_healthy(), effect::is_null(), and mutation_value().

Referenced by regen().

◆ hearing_ability()

float Character::hearing_ability ( ) const

Definition at line 10301 of file character.cpp.

10302{
10303 float volume_multiplier = 1.0;
10304
10305 // Mutation/Bionic volume modifiers
10307 volume_multiplier *= 3.5;
10308 }
10309 if( has_trait( trait_PER_SLIME ) ) {
10310 // Random hearing :-/
10311 // (when it's working at all, see player.cpp)
10312 // changed from 0.5 to fix Mac compiling error
10313 volume_multiplier *= ( rng( 1, 2 ) );
10314 }
10315
10316 volume_multiplier *= Character::mutation_value( "hearing_modifier" );
10317
10318 if( has_effect( effect_deaf ) ) {
10319 // Scale linearly up to 30 minutes
10320 volume_multiplier *= ( 30_minutes - get_effect_dur( effect_deaf ) ) / 30_minutes;
10321 }
10322
10323 if( has_effect( effect_earphones ) ) {
10324 volume_multiplier *= .25;
10325 }
10326
10327 return volume_multiplier;
10328}
static const trait_id trait_PER_SLIME("PER_SLIME")
static const efftype_id effect_deaf("deaf")
static const bionic_id bio_ears("bio_ears")
static const bionic_id bio_earplugs("bio_earplugs")
static const efftype_id effect_earphones("earphones")

References bio_earplugs, bio_ears, effect_deaf, effect_earphones, Creature::get_effect_dur(), has_active_bionic(), Creature::has_effect(), has_trait(), mutation_value(), rng(), and trait_PER_SLIME.

Referenced by can_hear(), and sounds::process_sound_markers().

◆ heat_emission()

void Character::heat_emission ( bionic bio,
int  fuel_energy 
)

Handle heat from exothermic power generation.

Definition at line 1496 of file bionics.cpp.

1497{
1498 if( !bio.info().exothermic_power_gen ) {
1499 return;
1500 }
1501 const float efficiency = bio.info().fuel_efficiency;
1502
1503 const int heat_prod = fuel_energy * ( 1.0f - efficiency );
1504 const int heat_level = std::min( heat_prod / 10, 4 );
1505 const emit_id hotness = emit_id( "emit_hot_air" + std::to_string( heat_level ) + "_cbm" );
1506 map &here = get_map();
1507 if( hotness.is_valid() ) {
1508 const int heat_spread = std::max( heat_prod / 10 - heat_level, 1 );
1509 here.emit_field( pos(), hotness, heat_spread );
1510 }
1511 for( const std::pair<const bodypart_str_id, int> &bp : bio.info().occupied_bodyparts ) {
1512 add_effect( effect_heating_bionic, 2_seconds, bp.first->token, heat_prod );
1513 }
1514}
static const efftype_id effect_heating_bionic("heating_bionic")
bool exothermic_power_gen
If true this bionic emits heat when producing power.
Definition: bionics.h:79
string_id< emit > emit_id
Definition: type_id.h:51

References Creature::add_effect(), effect_heating_bionic, bionic_data::exothermic_power_gen, bionic_data::fuel_efficiency, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), bionic::info(), string_id< T >::is_valid(), bionic_data::occupied_bodyparts, pos(), and to_string().

Referenced by burn_fuel(), and passive_power_gen().

◆ height()

int Character::height ( ) const

Definition at line 6844 of file character.cpp.

6845{
6846 switch( get_size() ) {
6847 case MS_TINY:
6848 return init_height - 100;
6849 case MS_SMALL:
6850 return init_height - 50;
6851 case MS_MEDIUM:
6852 return init_height;
6853 case MS_LARGE:
6854 return init_height + 50;
6855 case MS_HUGE:
6856 return init_height + 100;
6857 default:
6858 break;
6859 }
6860
6861 debugmsg( "Invalid size class" );
6862 abort();
6863}
@ MS_TINY
Definition: creature.h:58
@ MS_LARGE
Definition: creature.h:61
@ MS_SMALL
Definition: creature.h:59
@ MS_HUGE
Definition: creature.h:62
@ MS_MEDIUM
Definition: creature.h:60

References abort, debugmsg, get_size(), init_height, MS_HUGE, MS_LARGE, MS_MEDIUM, MS_SMALL, and MS_TINY.

Referenced by bodyweight(), height_string(), and set_base_height().

◆ height_string()

std::string Character::height_string ( ) const

Definition at line 6829 of file character.cpp.

6830{
6831 const bool metric = get_option<std::string>( "DISTANCE_UNITS" ) == "metric";
6832
6833 if( metric ) {
6834 std::string metric_string = _( "%d cm" );
6835 return string_format( metric_string, height() );
6836 }
6837
6838 int total_inches = std::round( height() / 2.54 );
6839 int feet = std::floor( total_inches / 12 );
6840 int remainder_inches = total_inches % 12;
6841 return string_format( "%d\'%d\"", feet, remainder_inches );
6842}

References _, height(), and string_format().

Referenced by draw_stats_info(), and draw_stats_tab().

◆ hit_roll()

float Character::hit_roll ( ) const
overridevirtual

Returns the player's basic hit roll that is compared to the target's dodge roll.

Implements Creature.

Definition at line 358 of file melee.cpp.

359{
360 // Dexterity, skills, weapon and martial arts
361 float hit = get_melee_hit_base();
362
363 // Farsightedness makes us hit worse
364 if( has_trait( trait_HYPEROPIC ) && !worn_with_flag( "FIX_FARSIGHT" ) &&
366 hit -= 2.0f;
367 }
368
369 //Unstable ground chance of failure
371 hit *= 0.75f;
372 }
373
374 hit *= std::max( 0.25f, 1.0f - encumb( bp_torso ) / 100.0f );
375
376 return melee::melee_hit_range( hit );
377}
float get_melee_hit_base() const
Returns weapon skill.
Definition: melee.cpp:352
float melee_hit_range(float accuracy)
Once the accuracy (sum of modifiers) of an attack has been determined, this is used to actually roll ...
Definition: melee.cpp:2503

References bp_torso, effect_bouldering, effect_contacts, encumb(), get_melee_hit_base(), Creature::has_effect(), has_trait(), melee::melee_hit_range(), trait_HYPEROPIC, and worn_with_flag().

Referenced by melee_attack(), perform_special_attacks(), scored_crit(), and avatar_funcs::try_disarm_npc().

◆ hitall()

int Character::hitall ( int  dam,
int  vary,
Creature source 
)

Harms all body parts for dam, with armor reduction.

If vary > 0 damage to parts are random within vary % (1-100)

Definition at line 8686 of file character.cpp.

8687{
8688 int damage_taken = 0;
8689 for( int i = 0; i < num_hp_parts; i++ ) {
8690 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
8691 int ddam = vary ? dam * rng( 100 - vary, 100 ) / 100 : dam;
8692 int cut = 0;
8693 auto damage = damage_instance::physical( ddam, cut, 0 );
8694 damage_taken += deal_damage( source, bp, damage ).total_damage();
8695 }
8696 return damage_taken;
8697}
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6487
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54

References convert_bp(), deal_damage(), hp_to_bp(), string_id< T >::id(), num_hp_parts, damage_instance::physical(), rng(), and dealt_damage_instance::total_damage().

Referenced by game::forced_door_closing(), and vehicle::part_collision().

◆ hp_percentage()

int Character::hp_percentage ( ) const
overridevirtual

Returns overall % of HP remaining.

Implements Creature.

Definition at line 11047 of file character.cpp.

11048{
11049 const bodypart_id head_id = bodypart_id( "head" );
11050 const bodypart_id torso_id = bodypart_id( "torso" );
11051 int total_cur = 0;
11052 int total_max = 0;
11053 // Head and torso HP are weighted 3x and 2x, respectively
11054 total_cur = get_part_hp_cur( head_id ) * 3 + get_part_hp_cur( torso_id ) * 2;
11055 total_max = get_part_hp_max( head_id ) * 3 + get_part_hp_max( torso_id ) * 2;
11056 for( const std::pair< const bodypart_str_id, bodypart> &elem : get_body() ) {
11057 total_cur += elem.second.get_hp_cur();
11058 total_max += elem.second.get_hp_max();
11059 }
11060
11061 return ( 100 * total_cur ) / total_max;
11062}

References Creature::get_body(), Creature::get_part_hp_cur(), and Creature::get_part_hp_max().

Referenced by npc::character_danger(), npc::emergency(), npc::hp_description(), and npc::process_turn().

◆ hp_to_bp()

body_part Character::hp_to_bp ( hp_part  hpart)
static

Converts an hp_part to a body_part.

Definition at line 6487 of file character.cpp.

6488{
6489 switch( hpart ) {
6490 case hp_head:
6491 return bp_head;
6492 case hp_torso:
6493 return bp_torso;
6494 case hp_arm_l:
6495 return bp_arm_l;
6496 case hp_arm_r:
6497 return bp_arm_r;
6498 case hp_leg_l:
6499 return bp_leg_l;
6500 case hp_leg_r:
6501 return bp_leg_r;
6502 default:
6503 return num_bp;
6504 }
6505}

References bp_arm_l, bp_arm_r, bp_head, bp_leg_l, bp_leg_r, bp_torso, hp_arm_l, hp_arm_r, hp_head, hp_leg_l, hp_leg_r, hp_torso, and num_bp.

Referenced by iexamine::autodoc(), cauterize_actor::cauterize_effect(), draw_limb_health(), heal_actor::finish_using(), hitall(), impact(), pick_part_to_heal(), map::player_in_field(), regen(), heal_actor::use_healing_item(), and npc::wear_if_wanted().

◆ hurtall()

void Character::hurtall ( int  dam,
Creature source,
bool  disturb = true 
)

Hurts all body parts for dam, no armor reduction.

Definition at line 8668 of file character.cpp.

8669{
8670 if( is_dead_state() || has_trait( trait_DEBUG_NODMG ) || dam <= 0 ) {
8671 return;
8672 }
8673
8674 for( const bodypart_id &bp : get_all_body_parts( true ) ) {
8675 // Don't use apply_damage here or it will annoy the player with 6 queries
8676 const int dam_to_bodypart = std::min( dam, get_part_hp_cur( bp ) );
8677 mod_part_hp_cur( bp, - dam_to_bodypart );
8678 g->events().send<event_type::character_takes_damage>( getID(), dam_to_bodypart );
8679 }
8680
8681 // Low pain: damage is spread all over the body, so not as painful as 6 hits in one part
8682 mod_pain( dam );
8683 on_hurt( source, disturb );
8684}

References character_takes_damage, g, Creature::get_all_body_parts(), Creature::get_part_hp_cur(), getID(), has_trait(), is_dead_state(), mod_pain(), Creature::mod_part_hp_cur(), on_hurt(), and trait_DEBUG_NODMG.

Referenced by trapfunc::drain(), hardcoded_effects(), marloss_common(), trapfunc::pit(), map::player_in_field(), game::process_artifact(), relic_funcs::process_recharge_entry(), regen(), map::shake_vehicle(), suffer_from_bad_bionics(), suffer_from_radiation(), trapfunc::tripwire(), and try_reject_mutagen().

◆ i_add()

item & Character::i_add ( item  it,
bool  should_stack = true 
)

Definition at line 2268 of file character.cpp.

2269{
2270 itype_id item_type_id = it.typeId();
2271 last_item = item_type_id;
2272
2273 if( it.is_food() || it.is_ammo() || it.is_gun() || it.is_armor() ||
2274 it.is_book() || it.is_tool() || it.is_melee() || it.is_food_container() ) {
2275 inv.unsort();
2276 }
2277
2278 // if there's a desired invlet for this item type, try to use it
2279 bool keep_invlet = false;
2280 const invlets_bitset cur_inv = allocated_invlets();
2281 for( auto iter : inv.assigned_invlet ) {
2282 if( iter.second == item_type_id && !cur_inv[iter.first] ) {
2283 it.invlet = iter.first;
2284 keep_invlet = true;
2285 break;
2286 }
2287 }
2288 auto &item_in_inv = inv.add_item( it, keep_invlet, true, should_stack );
2289 item_in_inv.on_pickup( *this );
2292 return item_in_inv;
2293}
@ reloadables
Definition: character.h:102
@ reloadable_cbms
Definition: character.h:103
itype_id last_item
Definition: character.h:1580
std::bitset< std::numeric_limits< char >::max()> allocated_invlets() const
Only use for UI things.
Definition: character.cpp:2495
std::map< char, itype_id > assigned_invlet
Definition: inventory.h:99
bool is_gun() const
Can this item be used to perform a ranged attack?
Definition: item.cpp:6527
bool is_food_container() const
Definition: item.cpp:6618
bool is_book() const
Definition: item.cpp:6719
bool is_ammo() const
Definition: item.cpp:6592
void on_pickup(Character &p)
Callback when a player starts carrying the item.
Definition: item.cpp:4538
bool is_melee(damage_type dt) const
Is this item an effective melee weapon for the given damage type?
Definition: item.cpp:6687

References inventory::add_item(), allocated_invlets(), inventory::assigned_invlet, clear_npc_ai_info_cache(), inv, item::invlet, item::is_ammo(), item::is_armor(), item::is_book(), item::is_food(), item::is_food_container(), item::is_gun(), item::is_melee(), item::is_tool(), last_item, item::on_pickup(), reloadable_cbms, reloadables, item::typeId(), and inventory::unsort().

Referenced by avatar_funcs::add_or_drop_with_msg(), iuse::adrenaline_injector(), iuse::arrow_flammable(), monexamine::attach_or_remove_saddle(), debug_menu::debug(), fetch_activity(), give_item_to(), handle_harvest(), i_add_or_drop(), mount_creature(), npc::mug_player(), iuse::multicooker(), item_location::impl::item_on_map::obtain(), item_location::impl::item_on_person::obtain(), item_location::impl::item_on_vehicle::obtain(), item_location::impl::item_in_container::obtain(), pick_one_up(), npc::pick_up_item(), iuse::purify_smart(), iuse::radiocar(), item::reload(), monexamine::remove_leash(), mattack::riotbot(), talk_effect_fun_t::set_bulk_trade_accept(), set_item_inventory(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_sell_item(), gun_actor::shoot(), spell_effect::spawn_ethereal_item(), npc::stow_item(), monexamine::take_items_from(), npc_trading::transfer_items(), avatar_funcs::try_steal_from_npc(), ammobelt_actor::use(), iuse::vaccine(), and avatar_action::wield().

◆ i_add_or_drop()

bool Character::i_add_or_drop ( item it,
int  qty = 1 
)

Sets invlet and adds to inventory if possible, drops otherwise, returns true if either succeeded.

An optional qty can be provided (and will perform better than separate calls).

Definition at line 2408 of file character.cpp.

2409{
2410 bool retval = true;
2411 bool drop = it.made_of( LIQUID );
2412 inv.assign_empty_invlet( it, *this );
2413 map &here = get_map();
2414 for( int i = 0; i < qty; ++i ) {
2415 drop |= !can_pick_weight( it, !get_option<bool>( "DANGEROUS_PICKUPS" ) ) || !can_pick_volume( it );
2416 if( drop ) {
2417 retval &= !here.add_item_or_charges( pos(), it ).is_null();
2418 } else {
2419 i_add( it );
2420 }
2421 }
2422
2423 return retval;
2424}
item & i_add(item it, bool should_stack=true)
Definition: character.cpp:2268
bool can_pick_volume(const item &it) const
Definition: character.cpp:2707
void assign_empty_invlet(item &it, const Character &p, bool force=false)
Definition: inventory.cpp:1152

References inventory::assign_empty_invlet(), can_pick_volume(), can_pick_weight(), drop(), get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), i_add(), inv, LIQUID, item::made_of(), and pos().

Referenced by activate_mutation(), salvage_actor::cut_up(), drop_or_handle(), heal_actor::finish_using(), avatar_funcs::gunmod_remove(), item_contents::handle_liquid_or_spill(), iexamine::pedestal_wyrm(), item::reload(), remove_radio_mod(), avatar_funcs::unload_item(), consume_drug_iuse::use(), bandolier_actor::use(), iexamine::vending(), and debug_menu::wishitem().

◆ i_add_to_container()

int Character::i_add_to_container ( const item it,
bool  unloading 
)

Try to find a container/s on character containing ammo of type it.typeId() and add charges until the container is full.

Parameters
unloadingDo not try to add to a container when the item was intentionally unloaded.
Returns
Remaining charges which could not be stored in a container.

Definition at line 2232 of file character.cpp.

2233{
2234 int charges = it.charges;
2235 if( !it.is_ammo() || unloading ) {
2236 return charges;
2237 }
2238
2239 const itype_id item_type = it.typeId();
2240 auto add_to_container = [&it, &charges]( item & container ) {
2241 auto &contained_ammo = container.contents.front();
2242 if( contained_ammo.charges < container.ammo_capacity() ) {
2243 const int diff = container.ammo_capacity() - contained_ammo.charges;
2244 //~ %1$s: item name, %2$s: container name
2245 add_msg( pgettext( "container", "You put the %1$s in your %2$s." ), it.tname(), container.tname() );
2246 if( diff > charges ) {
2247 contained_ammo.charges += charges;
2248 return 0;
2249 } else {
2250 contained_ammo.charges = container.ammo_capacity();
2251 return charges - diff;
2252 }
2253 }
2254 return charges;
2255 };
2256
2257 visit_items( [ & ]( item * item ) {
2258 if( charges > 0 && item->is_ammo_container() && item_type == item->contents.front().typeId() ) {
2259 charges = add_to_container( *item );
2260 item->handle_pickup_ownership( *this );
2261 }
2262 return VisitResponse::NEXT;
2263 } );
2264
2265 return charges;
2266}
bool is_ammo_container() const
Definition: item.cpp:6672
VisitResponse visit_items(const std::function< VisitResponse(item *, item *)> &func)
Traverses this object and any child items contained using a visitor pattern.
Definition: visitable.cpp:423

References add_msg(), item::charges, item::contents, item_contents::front(), item::is_ammo(), item::is_ammo_container(), NEXT, pgettext(), item::tname(), item::typeId(), and visitable< Character >::visit_items().

Referenced by avatar_funcs::add_or_drop_with_msg(), and pick_one_up().

◆ i_at() [1/2]

◆ i_at() [2/2]

const item & Character::i_at ( int  position) const

Definition at line 2333 of file character.cpp.

2334{
2335 if( position == -1 ) {
2336 return primary_weapon();
2337 }
2338 if( position < -1 ) {
2339 int worn_index = worn_position_to_index( position );
2340 if( static_cast<size_t>( worn_index ) < worn.size() ) {
2341 auto iter = worn.begin();
2342 std::advance( iter, worn_index );
2343 return *iter;
2344 }
2345 }
2346
2347 return inv.find_item( position );
2348}
const item & find_item(int position) const
Definition: inventory.cpp:801

References inventory::find_item(), inv, position, primary_weapon(), worn, and worn_position_to_index().

◆ i_rem() [1/2]

item Character::i_rem ( const item it)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
itA pointer to the item to be removed. The item must exists in the players possession (one can use has_item to check for this).
Returns
A copy of the removed item.

Definition at line 2391 of file character.cpp.

2392{
2393 auto tmp = remove_items_with( [&it]( const item & i ) {
2394 return &i == it;
2395 }, 1 );
2396 if( tmp.empty() ) {
2397 debugmsg( "did not found item %s to remove it!", it->tname() );
2398 return item();
2399 }
2400 return tmp.front();
2401}
std::list< item > remove_items_with(const std::function< bool(const item &)> &filter, int count=INT_MAX)
Removes items contained by this instance which match the filter.

References debugmsg, visitable< Character >::remove_items_with(), and item::tname().

◆ i_rem() [2/2]

item Character::i_rem ( int  pos)

Remove a specific item from player possession.

The item is compared by pointer. Contents of the item are removed as well.

Parameters
posThe item position of the item to be removed. The item must exists, use has_item to check this.
Returns
A copy of the removed item.

Definition at line 2373 of file character.cpp.

2374{
2375 item tmp;
2376 if( pos == -1 ) {
2377 tmp = primary_weapon();
2379 return tmp;
2380 } else if( pos < -1 && pos > worn_position_to_index( worn.size() ) ) {
2381 auto iter = worn.begin();
2382 std::advance( iter, worn_position_to_index( pos ) );
2383 tmp = *iter;
2384 tmp.on_takeoff( *this );
2385 worn.erase( iter );
2386 return tmp;
2387 }
2388 return inv.remove_item( pos );
2389}

References inv, item::on_takeoff(), pos(), primary_weapon(), inventory::remove_item(), set_primary_weapon(), worn, and worn_position_to_index().

Referenced by monexamine::add_leash(), apply_damage(), monexamine::attach_bag_to(), mattack::bio_op_disarm(), iuse::blood_draw(), consume(), consume_charges(), drop_invalid_inventory(), npc::drop_items(), iuse::fish_trap(), give_item_to(), activity_handlers::gunmod_add_finish(), ranged::handle_gun_damage(), i_rem_keep_contents(), monexamine::insert_battery(), invoke_item(), activity_handlers::lockpicking_finish(), iuse::lumber(), npc::mug_player(), npc_throw(), pickup::obtain_and_tokenize_items(), iuse::radiocar(), player::reduce_charges(), character_funcs::store_in_container(), tidy_activity(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), unpack_actor::use(), and avatar::wield().

◆ i_rem_keep_contents()

void Character::i_rem_keep_contents ( int  idx)

Definition at line 2403 of file character.cpp.

2404{
2405 i_rem( idx ).spill_contents( pos() );
2406}

References i_rem(), pos(), and item::spill_contents().

Referenced by damage_item(), and sew_advanced_actor::use().

◆ impact()

int Character::impact ( int  force,
const tripoint pos 
)
overridevirtual

Deals falling/collision damage with terrain/creature at pos.

Implements Creature.

Definition at line 10835 of file character.cpp.

10836{
10837 // Falls over ~30m are fatal more often than not
10838 // But that would be quite a lot considering 21 z-levels in game
10839 // so let's assume 1 z-level is comparable to 30 force
10840
10841 if( force <= 0 ) {
10842 return force;
10843 }
10844
10845 // Damage modifier (post armor)
10846 float mod = 1.0f;
10847 int effective_force = force;
10848 int cut = 0;
10849 // Percentage armor penetration - armor won't help much here
10850 // TODO: Make cushioned items like bike helmets help more
10851 float armor_eff = 1.0f;
10852 // Shock Absorber CBM heavily reduces damage
10853 const bool shock_absorbers = has_active_bionic( bionic_id( "bio_shock_absorber" ) );
10854
10855 // Being slammed against things rather than landing means we can't
10856 // control the impact as well
10857 const bool slam = p != pos();
10858 std::string target_name = "a swarm of bugs";
10859 Creature *critter = g->critter_at( p );
10860 if( critter != this && critter != nullptr ) {
10861 target_name = critter->disp_name();
10862 // Slamming into creatures and NPCs
10863 // TODO: Handle spikes/horns and hard materials
10864 armor_eff = 0.5f; // 2x as much as with the ground
10865 // TODO: Modify based on something?
10866 mod = 1.0f;
10867 effective_force = force;
10868 } else if( const optional_vpart_position vp = g->m.veh_at( p ) ) {
10869 // Slamming into vehicles
10870 // TODO: Integrate it with vehicle collision function somehow
10871 target_name = vp->vehicle().disp_name();
10872 if( vp.part_with_feature( "SHARP", true ) ) {
10873 // Now we're actually getting impaled
10874 cut = force; // Lots of fun
10875 }
10876
10877 mod = slam ? 1.0f : fall_damage_mod();
10878 armor_eff = 0.25f; // Not much
10879 if( !slam && vp->part_with_feature( "ROOF", true ) ) {
10880 // Roof offers better landing than frame or pavement
10881 // TODO: Make this not happen with heavy duty/plated roof
10882 effective_force /= 2;
10883 }
10884 } else {
10885 // Slamming into terrain/furniture
10886 target_name = g->m.disp_name( p );
10887 int hard_ground = g->m.has_flag( TFLAG_DIGGABLE, p ) ? 0 : 3;
10888 armor_eff = 0.25f; // Not much
10889 // Get cut by stuff
10890 // This isn't impalement on metal wreckage, more like flying through a closed window
10891 cut = g->m.has_flag( TFLAG_SHARP, p ) ? 5 : 0;
10892 effective_force = force + hard_ground;
10893 mod = slam ? 1.0f : fall_damage_mod();
10894 if( g->m.has_furn( p ) ) {
10895 // TODO: Make furniture matter
10896 } else if( g->m.has_flag( TFLAG_SWIMMABLE, p ) ) {
10897 // TODO: Some formula of swimming
10898 effective_force /= 4;
10899 }
10900 }
10901
10902 // Rescale for huge force
10903 // At >30 force, proper landing is impossible and armor helps way less
10904 if( effective_force > 30 ) {
10905 // Armor simply helps way less
10906 armor_eff *= 30.0f / effective_force;
10907 if( mod < 1.0f ) {
10908 // Everything past 30 damage gets a worse modifier
10909 const float scaled_mod = std::pow( mod, 30.0f / effective_force );
10910 const float scaled_damage = ( 30.0f * mod ) + scaled_mod * ( effective_force - 30.0f );
10911 mod = scaled_damage / effective_force;
10912 }
10913 }
10914
10915 if( !slam && mod < 1.0f && mod * force < 5 ) {
10916 // Perfect landing, no damage (regardless of armor)
10917 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10918 return 0;
10919 }
10920
10921 // Shock absorbers kick in only when they need to, so if our other protections fail, fall back on them
10922 if( shock_absorbers ) {
10923 effective_force -= 15; // Provide a flat reduction to force
10924 if( mod > 0.25f ) {
10925 mod = 0.25f; // And provide a 75% reduction against that force if we don't have it already
10926 }
10927 if( effective_force < 0 ) {
10928 effective_force = 0;
10929 }
10930 }
10931
10932 int total_dealt = 0;
10933 if( mod * effective_force >= 5 ) {
10934 for( int i = 0; i < num_hp_parts; i++ ) {
10935 const bodypart_id bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
10936 const int bash = effective_force * rng( 60, 100 ) / 100;
10937 damage_instance di;
10938 di.add_damage( DT_BASH, bash, 0, armor_eff, mod );
10939 // No good way to land on sharp stuff, so here modifier == 1.0f
10940 di.add_damage( DT_CUT, cut, 0, armor_eff, 1.0f );
10941 total_dealt += deal_damage( nullptr, bp, di ).total_damage();
10942 }
10943 }
10944
10945 if( total_dealt > 0 && is_player() ) {
10946 // "You slam against the dirt" is fine
10947 add_msg( m_bad, _( "You are slammed against %1$s for %2$d damage." ),
10948 target_name, total_dealt );
10949 } else if( is_player() && shock_absorbers ) {
10950 add_msg( m_bad, _( "You are slammed against %s!" ),
10951 target_name, total_dealt );
10952 add_msg( m_good, _( "…but your shock absorbers negate the damage!" ) );
10953 } else if( slam ) {
10954 // Only print this line if it is a slam and not a landing
10955 // Non-players should only get this one: player doesn't know how much damage was dealt
10956 // and landing messages for each slammed creature would be too much
10958 _( "You are slammed against %s." ),
10959 _( "<npcname> is slammed against %s." ),
10960 target_name );
10961 } else {
10962 // No landing message for NPCs
10963 add_msg_if_player( m_warning, _( "You land on %s." ), target_name );
10964 }
10965
10966 if( x_in_y( mod, 1.0f ) ) {
10967 add_effect( effect_downed, rng( 1_turns, 1_turns + mod * 3_turns ) );
10968 }
10969
10970 return total_dealt;
10971}
float fall_damage_mod() const override
Returns multiplier on fall damage at low velocity (knockback/pit/1 z-level, not 5 z-levels)
@ TFLAG_DIGGABLE
Definition: mapdata.h:298
@ TFLAG_SWIMMABLE
Definition: mapdata.h:280
@ TFLAG_SHARP
Definition: mapdata.h:297
void bash(const spell &sp, Creature &caster, const tripoint &target)

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), spell_effect::bash(), bionic_id, convert_bp(), deal_damage(), Creature::disp_name(), DT_BASH, DT_CUT, effect_downed, fall_damage_mod(), g, has_active_bionic(), hp_to_bp(), string_id< T >::id(), Creature::is_player(), m_bad, m_good, m_warning, num_hp_parts, pos(), rng(), TFLAG_DIGGABLE, TFLAG_SHARP, TFLAG_SWIMMABLE, dealt_damage_instance::total_damage(), and x_in_y().

Referenced by trapfunc::ledge().

◆ in_climate_control()

bool Character::in_climate_control ( )

Returns true if the player is in a climate controlled area or armor.

Definition at line 3853 of file character.cpp.

3854{
3855 bool regulated_area = false;
3856 // Check
3858 return true;
3859 }
3860 map &here = get_map();
3861 if( has_trait( trait_M_SKIN3 ) && here.has_flag_ter_or_furn( flag_FUNGUS, pos() ) &&
3862 in_sleep_state() ) {
3863 return true;
3864 }
3865 for( auto &w : worn ) {
3866 if( w.has_flag( flag_CLIMATE_CONTROL.str() ) ) {
3867 return true;
3868 }
3869 }
3871 // save CPU and simulate acclimation.
3873 if( const optional_vpart_position vp = here.veh_at( pos() ) ) {
3874 // TODO: (?) Force player to scrounge together an AC unit
3875 regulated_area = (
3876 vp->is_inside() && // Already checks for opened doors
3877 vp->vehicle().total_power_w( true ) > 0 // Out of gas? No AC for you!
3878 );
3879 }
3880 // TODO: AC check for when building power is implemented
3881 last_climate_control_ret = regulated_area;
3882 if( !regulated_area ) {
3883 // Takes longer to cool down / warm up with AC, than it does to step outside and feel cruddy.
3884 next_climate_control_check += 40_turns;
3885 }
3886 } else {
3888 }
3889 return regulated_area;
3890}
static const trait_id trait_M_SKIN3("M_SKIN3")
static const flag_str_id flag_CLIMATE_CONTROL("CLIMATE_CONTROL")
static const bionic_id bio_climate("bio_climate")
static const std::string flag_FUNGUS("FUNGUS")

References bio_climate, flag_CLIMATE_CONTROL, flag_FUNGUS(), get_map(), has_active_bionic(), has_trait(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), in_sleep_state(), last_climate_control_ret, next_climate_control_check, pos(), string_id< T >::str(), trait_M_SKIN3, calendar::turn, and worn.

Referenced by update_bodytemp().

◆ in_sleep_state()

◆ in_species()

bool Character::in_species ( const species_id spec) const
overridevirtual

Reimplemented from Creature.

Definition at line 529 of file character.cpp.

530{
531 return spec == HUMAN;
532}
static const species_id HUMAN("HUMAN")

References HUMAN.

◆ initialize_stomach_contents()

void Character::initialize_stomach_contents ( )

Definition at line 195 of file stomach.cpp.

196{
198}

References stomach.

◆ install_bionics()

bool Character::install_bionics ( const itype type,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 2299 of file bionics.cpp.

2301{
2302 if( !type.bionic ) {
2303 debugmsg( "Tried to install NULL bionic" );
2304 return false;
2305 }
2306
2307 const bionic_id &bioid = type.bionic->id;
2308 const bionic_id &upbioid = bioid->upgraded_bionic;
2309 const int difficulty = type.bionic->difficulty;
2310 float adjusted_skill;
2311 int pl_skill;
2312 if( autodoc ) {
2313 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2316 skill_level );
2317 pl_skill = installer.bionics_pl_skill( skill_firstaid,
2320 skill_level );
2321 } else {
2322 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2325 skill_level );
2326 pl_skill = installer.bionics_pl_skill( skill_electronics,
2329 skill_level );
2330 }
2331 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty );
2332
2333 // Practice skills only if conducting manual installation
2334 if( !autodoc ) {
2335 installer.practice( skill_electronics, static_cast<int>( ( 100 - chance_of_success ) * 1.5 ) );
2336 installer.practice( skill_firstaid, static_cast<int>( ( 100 - chance_of_success ) * 1.0 ) );
2337 installer.practice( skill_mechanics, static_cast<int>( ( 100 - chance_of_success ) * 0.5 ) );
2338 }
2339
2340 int success = chance_of_success - rng( 0, 99 );
2341 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2342 perform_install( bioid, upbioid, difficulty, success, pl_skill, "NOT_MED",
2343 bioid->canceled_mutations );
2344 return true;
2345 }
2346 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2347 activity.values.push_back( difficulty );
2348 activity.values.push_back( success );
2349 activity.values.push_back( units::to_joule( bioid->capacity ) );
2350 activity.values.push_back( pl_skill );
2351 activity.str_values.push_back( "install" );
2352 activity.str_values.push_back( bioid.str() );
2353
2354 if( installer.has_trait( trait_PROF_MED ) || installer.has_trait( trait_PROF_AUTODOC ) ) {
2355 activity.str_values.push_back( installer.disp_name( true ) );
2356 } else {
2357 activity.str_values.push_back( "NOT_MED" );
2358 }
2359 if( autodoc ) {
2360 activity.str_values.push_back( "true" );
2361 } else {
2362 activity.str_values.push_back( "false" );
2363 }
2364 for( const std::pair<const bodypart_str_id, int> &elem : bioid->occupied_bodyparts ) {
2365 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2366 }
2367
2368 return true;
2369}
static const activity_id ACT_OPERATION("ACT_OPERATION")
void perform_install(bionic_id bid, bionic_id upbid, int difficulty, int success, int pl_skill, const std::string &installer_name, const std::vector< trait_id > &trait_to_rem)
Success or failure of installation happens here.
Definition: bionics.cpp:2371
void practice(const skill_id &id, int amount, int cap=99, bool suppress_warning=false)
This handles giving xp for a skill.
Definition: character.cpp:3416
std::vector< std::string > str_values
constexpr value_type to_joule(const quantity< value_type, energy_in_joule_tag > &v)
Definition: units_energy.h:40
bionic_id upgraded_bionic
Id of another bionic which this bionic can upgrade.
Definition: bionics.h:131

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::canceled_mutations, bionic_data::capacity, debugmsg, disp_name(), effect_under_op, has_trait(), bionic_data::occupied_bodyparts, perform_install(), practice(), rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_joule(), trait_DEBUG_BIONICS, trait_PROF_AUTODOC, trait_PROF_MED, type, bionic_data::upgraded_bionic, and player_activity::values.

Referenced by iexamine::autodoc(), and install_bionic_actor::use().

◆ introduce_into_anesthesia()

void Character::introduce_into_anesthesia ( const time_duration duration,
player installer,
bool  needs_anesthesia 
)

Handles process of introducing patient into anesthesia during Autodoc operations.

Requires anesthesia kits or NOPAIN mutation

Definition at line 2885 of file bionics.cpp.

2887{
2888 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2889 installer.add_msg_if_player( m_info,
2890 _( "You tell the pain to bug off and proceed with the operation." ) );
2891 return;
2892 }
2893 installer.add_msg_player_or_npc( m_info,
2894 _( "You set up the operation step-by-step, configuring the Autodoc to manipulate a CBM." ),
2895 _( "<npcname> sets up the operation, configuring the Autodoc to manipulate a CBM." ) );
2896
2898 _( "You settle into position, sliding your right wrist into the couch's strap." ),
2899 _( "<npcname> settles into position, sliding their wrist into the couch's strap." ) );
2900 if( needs_anesthesia ) {
2901 //post-threshold medical mutants do not fear operations.
2904 _( "You feel excited as the operation starts." ) );
2905 }
2906
2908 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2909
2910 //post-threshold medical mutants with Deadened don't need anesthesia due to their inability to feel pain
2911 } else {
2912 //post-threshold medical mutants do not fear operations.
2915 _( "You feel excited as the Autodoc slices painlessly into you. You enjoy the sight of scalpels slicing you apart." ) );
2916 } else {
2918 _( "You stay very, very still, focusing intently on an interesting stain on the ceiling, as the Autodoc slices painlessly into you." ) );
2919 }
2920 }
2921
2922 //Pain junkies feel sorry about missed pain from operation.
2926 _( "As your consciousness slips away, you feel regret that you won't be able to enjoy the operation." ) );
2927 }
2928
2929 if( has_effect( effect_narcosis ) ) {
2930 const time_duration remaining_time = get_effect_dur( effect_narcosis );
2931 if( remaining_time <= duration ) {
2932 const time_duration top_off_time = duration - remaining_time;
2933 add_effect( effect_narcosis, top_off_time );
2934 fall_asleep( top_off_time );
2935 }
2936 } else {
2937 add_effect( effect_narcosis, duration );
2938 fall_asleep( duration );
2939 }
2940}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_THRESH_MEDICAL("THRESH_MEDICAL")
static const trait_id trait_MASOCHIST_MED("MASOCHIST_MED")
static const trait_id trait_CENOBITE("CENOBITE")
static const trait_id trait_MASOCHIST("MASOCHIST")
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:372
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:367

References _, Creature::add_effect(), Creature::add_msg_if_player(), player::add_msg_if_player(), Creature::add_msg_player_or_npc(), player::add_msg_player_or_npc(), effect_narcosis, fall_asleep(), Creature::get_effect_dur(), Creature::has_effect(), has_trait(), m_info, m_mixed, trait_CENOBITE, trait_DEBUG_BIONICS, trait_MASOCHIST, trait_MASOCHIST_MED, and trait_THRESH_MEDICAL.

Referenced by iexamine::autodoc().

◆ inv_dump()

std::vector< item * > Character::inv_dump ( )

Definition at line 8966 of file character.cpp.

8967{
8968 std::vector<item *> ret;
8969 if( is_armed() && can_unwield( primary_weapon() ).success() ) {
8970 ret.push_back( &primary_weapon() );
8971 }
8972 for( auto &i : worn ) {
8973 ret.push_back( &i );
8974 }
8975 inv.dump( ret );
8976 return ret;
8977}
void dump(std::vector< item * > &dest)
Definition: inventory.cpp:792

References can_unwield(), inventory::dump(), inv, is_armed(), primary_weapon(), cata::hash64_detail::ret, behavior::success, and worn.

Referenced by npc::apply_ownership_to_inv(), are_requirements_nearby(), npc::die(), generic_multi_activity_locations(), irradiate(), game::load(), item_action_generator::map_actions_to_items(), place_corpse(), conditional_t< T >::set_has_stolen_item(), sleep(), game::start_game(), and tidy_activity().

◆ invalidate_crafting_inventory()

◆ invlet_to_item()

item * Character::invlet_to_item ( int  invlet)

Return the item pointer of the item with given invlet, return nullptr if the player does not have such an item with that invlet.

Don't use this on npcs. Only use the invlet in the user interface, otherwise always use the item position.

Definition at line 2309 of file character.cpp.

2310{
2311 // Invlets may come from curses, which may also return any kind of key codes, those being
2312 // of type int and they can become valid, but different characters when casted to char.
2313 // Example: KEY_NPAGE (returned when the player presses the page-down key) is 0x152,
2314 // casted to char would yield 0x52, which happens to be 'R', a valid invlet.
2315 if( linvlet > std::numeric_limits<char>::max() || linvlet < std::numeric_limits<char>::min() ) {
2316 return nullptr;
2317 }
2318 const char invlet = static_cast<char>( linvlet );
2319 item *invlet_item = nullptr;
2320 visit_items( [&invlet, &invlet_item]( item * it ) {
2321 if( it->invlet == invlet ) {
2322 invlet_item = it;
2323 return VisitResponse::ABORT;
2324 }
2325 // Visit top-level items only as UIs don't support nested items.
2326 // Also, inventory restack logic depends on this.
2327 return VisitResponse::SKIP;
2328 } );
2329 return invlet_item;
2330}

References item::invlet, SKIP, and visitable< Character >::visit_items().

Referenced by pick_one_up(), game_menus::inv::reassign_letter(), inventory::restack(), show_armor_layers_ui(), and game_menus::inv::swap_letters().

◆ invoke_item() [1/4]

bool Character::invoke_item ( item used)
virtual

As above two, but with position equal to current position.

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7226 of file character.cpp.

7227{
7228 return invoke_item( used, pos() );
7229}

References invoke_item(), and pos().

◆ invoke_item() [2/4]

bool Character::invoke_item ( item used,
const std::string &  method 
)
virtual

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7236 of file character.cpp.

7237{
7238 return invoke_item( used, method, pos() );
7239}

References invoke_item(), and pos().

◆ invoke_item() [3/4]

bool Character::invoke_item ( item used,
const std::string &  method,
const tripoint pt 
)
virtual

As above, but with a pre-selected method.

Debugmsg if this item doesn't have this method.

Reimplemented in avatar, npc, and avatar.

Definition at line 7241 of file character.cpp.

7242{
7243 if( !has_enough_charges( *used, true ) ) {
7244 return false;
7245 }
7246
7247 item *actually_used = used->get_usable_item( method );
7248 if( actually_used == nullptr ) {
7249 debugmsg( "Tried to invoke a method %s on item %s, which doesn't have this method",
7250 method.c_str(), used->tname() );
7251 return false;
7252 }
7253
7254 int charges_used = actually_used->type->invoke( *this->as_player(), *actually_used, pt, method );
7255 if( charges_used == 0 ) {
7256 return false;
7257 }
7258 // Prevent accessing the item as it may have been deleted by the invoked iuse function.
7259
7260 if( used->is_tool() || used->is_medication() || used->get_contained().is_medication() ) {
7261 return consume_charges( *actually_used, charges_used );
7262 } else if( used->is_bionic() || used->is_deployable() || method == "place_trap" ) {
7263 i_rem( used );
7264 return true;
7265 }
7266
7267 return false;
7268}
bool has_enough_charges(const item &it, bool show_msg) const
Has the item enough charges to invoke its use function? Also checks if UPS from this player is used i...
Definition: character.cpp:7365
bool consume_charges(item &used, int qty)
Consume charges of a tool or comestible item, potentially destroying it in the process.
Definition: character.cpp:7420
bool is_deployable() const
Definition: item.cpp:6963
item * get_usable_item(const std::string &use_name)
Checks this item and its contents (recursively) for types that have use_function with type use_name.
Definition: item.cpp:7975
bool is_bionic() const
Definition: item.cpp:6562

References Creature::as_player(), consume_charges(), debugmsg, item::get_contained(), item::get_usable_item(), has_enough_charges(), i_rem(), itype::invoke(), item::is_bionic(), item::is_deployable(), item::is_medication(), item::is_tool(), item::tname(), and item::type.

◆ invoke_item() [4/4]

bool Character::invoke_item ( item ,
const tripoint pt 
)
virtual

Asks how to use the item (if it has more than one use_method) and uses it.

Returns true if it destroys the item. Consumes charges from the item. Multi-use items are ONLY supported when all use_methods are iuse_actor!

Reimplemented in avatar, npc, avatar, and npc.

Definition at line 7231 of file character.cpp.

7232{
7233 return false;
7234}

Referenced by activate_bionic(), activate_mutation(), invoke_item(), avatar::invoke_item(), npc::invoke_item(), and iexamine::use_furn_fake_item().

◆ irradiate()

bool Character::irradiate ( float  rads,
bool  bypass = false 
)

Handles mitigation and application of radiation.

Definition at line 1589 of file suffer.cpp.

1590{
1591 int rad_mut = 0;
1592 if( has_trait( trait_RADIOACTIVE3 ) ) {
1593 rad_mut = 3;
1594 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1595 rad_mut = 2;
1596 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1597 rad_mut = 1;
1598 }
1599
1600 if( rads > 0 ) {
1601 bool has_helmet = false;
1602 const bool power_armored = is_wearing_power_armor( &has_helmet );
1603 const bool rad_resist = power_armored || worn_with_flag( "RAD_RESIST" );
1604
1605 if( is_rad_immune() && !bypass ) {
1606 // Power armor and some high-tech gear protects completely from radiation
1607 rads = 0.0f;
1608 } else if( rad_resist && !bypass ) {
1609 rads /= 4.0f;
1610 }
1611
1612 if( has_effect( effect_iodine ) ) {
1613 // Radioactive mutation makes iodine less efficient (but more useful)
1614 rads *= 0.3f + 0.1f * rad_mut;
1615 }
1616
1617 int rads_max = roll_remainder( rads );
1618 mod_rad( rng( 0, rads_max ) );
1619
1620 // Apply rads to any radiation badges.
1621 for( item *const it : inv_dump() ) {
1622 if( it->typeId() != itype_rad_badge ) {
1623 continue;
1624 }
1625
1626 // Actual irradiation levels of badges and the player aren't precisely matched.
1627 // This is intentional.
1628 const int before = it->irradiation;
1629
1630 const int delta = rng( 0, rads_max );
1631 if( delta == 0 ) {
1632 continue;
1633 }
1634
1635 it->irradiation += delta;
1636
1637 // If in inventory (not worn), don't print anything.
1638 if( inv.has_item( *it ) ) {
1639 continue;
1640 }
1641
1642 // If the color hasn't changed, don't print anything.
1643 const std::string &col_before = rad_badge_color( before );
1644 const std::string &col_after = rad_badge_color( it->irradiation );
1645 if( col_before == col_after ) {
1646 continue;
1647 }
1648
1649 add_msg_if_player( m_warning, _( "Your radiation badge changes from %1$s to %2$s!" ),
1650 col_before, col_after );
1651 }
1652
1653 if( rads > 0.0f ) {
1654 return true;
1655 }
1656 }
1657 return false;
1658}
void mod_rad(int mod)
Definition: character.cpp:7085
std::vector< item * > inv_dump()
Definition: character.cpp:8966
bool is_rad_immune() const
Returns true if the player is protected from radiation.
Definition: character.cpp:6200
std::string rad_badge_color(const int rad)
Definition: item.cpp:294
static const trait_id trait_RADIOACTIVE2("RADIOACTIVE2")
static const trait_id trait_RADIOACTIVE3("RADIOACTIVE3")
static const trait_id trait_RADIOACTIVE1("RADIOACTIVE1")
static const itype_id itype_rad_badge("rad_badge")
static const efftype_id effect_iodine("iodine")

References _, Creature::add_msg_if_player(), effect_iodine, Creature::has_effect(), visitable< T >::has_item(), has_trait(), inv, inv_dump(), is_rad_immune(), is_wearing_power_armor(), itype_rad_badge, m_warning, mod_rad(), rad_badge_color(), rng(), roll_remainder(), trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, and worn_with_flag().

Referenced by trapfunc::glow(), hardcoded_effects(), modify_radiation(), map::player_in_field(), game::process_artifact(), mattack::science(), and suffer_from_radiation().

◆ is_armed()

◆ is_auto_moving()

bool Character::is_auto_moving ( ) const

Definition at line 10512 of file character.cpp.

10513{
10514 return destination_point.has_value();
10515}

References destination_point.

Referenced by game::handle_action(), and avatar_action::move().

◆ is_blind()

bool Character::is_blind ( ) const

◆ is_category_allowed() [1/2]

bool Character::is_category_allowed ( const std::string &  category) const

Definition at line 394 of file mutation.cpp.

395{
396 bool allowed = false;
397 bool restricted = false;
398 for( const trait_id &mut : get_mutations() ) {
399 for( const std::string &Ch_cat : mut.obj().allowed_category ) {
400 restricted = true;
401 if( Ch_cat == category ) {
402 allowed = true;
403 }
404 }
405 }
406 if( !restricted ) {
407 allowed = true;
408 }
409 return allowed;
410}

References get_mutations().

◆ is_category_allowed() [2/2]

bool Character::is_category_allowed ( const std::vector< std::string > &  category) const

Returns true if this category of mutation is allowed.

Definition at line 371 of file mutation.cpp.

372{
373 bool allowed = false;
374 bool restricted = false;
375 for( const trait_id &mut : get_mutations() ) {
376 if( !mut.obj().allowed_category.empty() ) {
377 restricted = true;
378 }
379 for( const std::string &Mu_cat : category ) {
380 if( mut.obj().allowed_category.count( Mu_cat ) ) {
381 allowed = true;
382 break;
383 }
384 }
385
386 }
387 if( !restricted ) {
388 allowed = true;
389 }
390 return allowed;
391
392}

References get_mutations().

Referenced by mutation_ok(), and old_mutate().

◆ is_dead_state()

bool Character::is_dead_state ( ) const
overridevirtual

Returns true if the character should be dead.

Implements Creature.

Definition at line 499 of file character.cpp.

500{
501 const auto all_bps = get_all_body_parts( true );
502
503 return std::any_of( all_bps.begin(), all_bps.end(), [this]( const bodypart_id & bp ) {
504 return bp->essential && get_part_hp_cur( bp ) <= 0;
505 } );
506}

References Creature::get_all_body_parts().

Referenced by apply_damage(), block_hit(), game::do_turn(), game::handle_action(), hurtall(), npc::is_dead(), game::is_game_over(), on_dodge(), vehicle_part::set_crew(), npc::talk_to_u(), game::win(), and game::win_screen().

◆ is_deaf()

◆ is_elec_immune()

bool Character::is_elec_immune ( ) const
overridevirtual

Returns true is the player is protected from electric shocks.

Implements Creature.

Definition at line 6130 of file character.cpp.

6131{
6132 return is_immune_damage( DT_ELECTRIC );
6133}
bool is_immune_damage(damage_type) const override
Returns true if the player is immune to this kind of damage.
Definition: character.cpp:6157

References DT_ELECTRIC, and is_immune_damage().

Referenced by iuse::ehandcuffs(), is_immune_field(), and map::player_in_field().

◆ is_hauling()

bool Character::is_hauling ( ) const

Definition at line 9191 of file character.cpp.

9192{
9193 return hauling;
9194}
bool hauling
Definition: character.h:1572

References hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), game::vertical_move(), and game::walk_move().

◆ is_hibernating()

bool Character::is_hibernating ( ) const

Returns if the player has hibernation mutation and is asleep and well fed.

Definition at line 5186 of file character.cpp.

References effect_sleep, get_kcal_percent(), get_thirst(), has_active_mutation(), Creature::has_effect(), trait_HIBERNATE, and very_thirsty.

Referenced by calc_needs_rates(), and update_needs().

◆ is_immune_damage()

bool Character::is_immune_damage ( damage_type  dt) const
overridevirtual

Returns true if the player is immune to this kind of damage.

Implements Creature.

Definition at line 6157 of file character.cpp.

6158{
6159 switch( dt ) {
6160 case DT_NULL:
6161 return true;
6162 case DT_TRUE:
6163 return false;
6164 case DT_BIOLOGICAL:
6165 return has_effect_with_flag( "EFFECT_BIO_IMMUNE" ) ||
6166 worn_with_flag( "BIO_IMMUNE" );
6167 case DT_BASH:
6168 return has_effect_with_flag( "EFFECT_BASH_IMMUNE" ) ||
6169 worn_with_flag( "BASH_IMMUNE" );
6170 case DT_CUT:
6171 return has_effect_with_flag( "EFFECT_CUT_IMMUNE" ) ||
6172 worn_with_flag( "CUT_IMMUNE" );
6173 case DT_ACID:
6174 return has_trait( trait_ACIDPROOF ) ||
6175 has_effect_with_flag( "EFFECT_ACID_IMMUNE" ) ||
6176 worn_with_flag( "ACID_IMMUNE" );
6177 case DT_STAB:
6178 return has_effect_with_flag( "EFFECT_STAB_IMMUNE" ) ||
6179 worn_with_flag( "STAB_IMMUNE" );
6180 case DT_BULLET:
6181 return has_effect_with_flag( "EFFECT_BULLET_IMMUNE" ) || worn_with_flag( "BULLET_IMMUNE" );
6182 case DT_HEAT:
6183 return has_trait( trait_M_SKIN2 ) ||
6185 has_effect_with_flag( "EFFECT_HEAT_IMMUNE" ) ||
6186 worn_with_flag( "HEAT_IMMUNE" );
6187 case DT_COLD:
6188 return has_effect_with_flag( "EFFECT_COLD_IMMUNE" ) ||
6189 worn_with_flag( "COLD_IMMUNE" );
6190 case DT_ELECTRIC:
6191 return has_active_bionic( bio_faraday ) ||
6192 worn_with_flag( "ELECTRIC_IMMUNE" ) ||
6194 has_effect_with_flag( "EFFECT_ELECTRIC_IMMUNE" );
6195 default:
6196 return true;
6197 }
6198}
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const bionic_id bio_faraday("bio_faraday")
@ AEP_RESIST_ELECTRICITY
Definition: enums.h:117

References AEP_RESIST_ELECTRICITY, bio_faraday, DT_ACID, DT_BASH, DT_BIOLOGICAL, DT_BULLET, DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, DT_NULL, DT_STAB, DT_TRUE, has_active_bionic(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), trait_ACIDPROOF, trait_M_SKIN2, trait_M_SKIN3, and worn_with_flag().

Referenced by character_funcs::is_bp_immune_to(), is_elec_immune(), and is_immune_effect().

◆ is_immune_effect()

bool Character::is_immune_effect ( const efftype_id eff) const
overridevirtual

Returns true if the player is immune to this kind of effect.

Implements Creature.

Definition at line 6135 of file character.cpp.

6136{
6137 if( eff == effect_downed ) {
6139 } else if( eff == effect_onfire ) {
6140 return is_immune_damage( DT_HEAT );
6141 } else if( eff == effect_deaf ) {
6143 has_bionic( bio_ears ) ||
6145 } else if( eff == effect_corroding ) {
6147 } else if( eff == effect_nausea ) {
6149 } else if( eff == effect_bleed ) {
6150 // Ugly, it was badly implemented and should be a flag
6151 return mutation_value( "bleed_resist" ) > 0.0f;
6152 }
6153
6154 return false;
6155}
static const trait_id trait_SLIMY("SLIMY")
static const trait_id trait_LEG_TENT_BRACE("LEG_TENT_BRACE")
static const trait_id trait_STRONGSTOMACH("STRONGSTOMACH")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const efftype_id effect_corroding("corroding")
static const trait_id trait_VISCOUS("VISCOUS")
static const std::string flag_PARTIAL_DEAF("PARTIAL_DEAF")
static const efftype_id effect_nausea("nausea")
double footwear_factor() const
Returns 1 if the player is wearing something on both feet, .5 if on one, and 0 if on neither.
Definition: character.cpp:8942
bool is_throw_immune() const
Returns true if the player is immune to throws.

References bio_ears, DT_ACID, DT_HEAT, effect_bleed, effect_corroding, effect_deaf, effect_downed, effect_nausea, effect_onfire, flag_DEAF(), flag_PARTIAL_DEAF(), footwear_factor(), has_bionic(), has_trait(), is_immune_damage(), is_throw_immune(), is_wearing(), itype_rm13_armor_on, mutation_value(), trait_LEG_TENT_BRACE, trait_SLIMY, trait_STRONGSTOMACH, trait_VISCOUS, and worn_with_flag().

Referenced by sounds::process_sound_markers().

◆ is_immune_field()

bool Character::is_immune_field ( const field_type_id ) const
overridevirtual

Returns true if we are immune to the field type with the given fid.

Does not handle intensity, so this function should only be called through is_dangerous_field().

Reimplemented from Creature.

Definition at line 6089 of file character.cpp.

6090{
6091 // Obviously this makes us invincible
6092 if( has_trait( trait_DEBUG_NODMG ) ) {
6093 return true;
6094 }
6095 // Check to see if we are immune
6096 const field_type &ft = fid.obj();
6097 for( const trait_id &t : ft.immunity_data_traits ) {
6098 if( has_trait( t ) ) {
6099 return true;
6100 }
6101 }
6102 bool immune_by_body_part_resistance = !ft.immunity_data_body_part_env_resistance.empty();
6103 for( const std::pair<body_part, int> &fide : ft.immunity_data_body_part_env_resistance ) {
6104 immune_by_body_part_resistance = immune_by_body_part_resistance &&
6105 get_env_resist( convert_bp( fide.first ).id() ) >= fide.second;
6106 }
6107 if( immune_by_body_part_resistance ) {
6108 return true;
6109 }
6110 if( ft.has_elec ) {
6111 return is_elec_immune();
6112 }
6113 if( ft.has_fire ) {
6115 }
6116 if( ft.has_acid ) {
6117 return !is_on_ground() && get_env_resist( bodypart_id( "foot_l" ) ) >= 15 &&
6118 get_env_resist( bodypart_id( "foot_r" ) ) >= 15 &&
6119 get_env_resist( bodypart_id( "leg_l" ) ) >= 15 &&
6120 get_env_resist( bodypart_id( "leg_r" ) ) >= 15 &&
6121 get_armor_type( DT_ACID, bodypart_id( "foot_l" ) ) >= 5 &&
6122 get_armor_type( DT_ACID, bodypart_id( "foot_r" ) ) >= 5 &&
6123 get_armor_type( DT_ACID, bodypart_id( "leg_l" ) ) >= 5 &&
6124 get_armor_type( DT_ACID, bodypart_id( "leg_r" ) ) >= 5;
6125 }
6126 // If we haven't found immunity yet fall up to the next level
6127 return Creature::is_immune_field( fid );
6128}
static const bionic_id bio_heatsink("bio_heatsink")
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6130
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:897
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7032
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:331
std::vector< trait_id > immunity_data_traits
Definition: field_type.h:173
bool has_elec
Definition: field_type.h:165
bool has_acid
Definition: field_type.h:164
bool has_fire
Definition: field_type.h:163
std::vector< std::pair< body_part, int > > immunity_data_body_part_env_resistance
Definition: field_type.h:174

References bio_heatsink, convert_bp(), DT_ACID, get_armor_type(), get_env_resist(), field_type::has_acid, has_active_bionic(), field_type::has_elec, field_type::has_fire, has_trait(), string_id< T >::id(), field_type::immunity_data_body_part_env_resistance, field_type::immunity_data_traits, is_elec_immune(), Creature::is_immune_field(), is_on_ground(), is_wearing(), itype_rm13_armor_on, int_id< T >::obj(), and trait_DEBUG_NODMG.

◆ is_invisible()

bool Character::is_invisible ( ) const

Definition at line 6288 of file character.cpp.

6289{
6290 return (
6295 );
6296}
static const std::string flag_EFFECT_INVISIBLE("EFFECT_INVISIBLE")

References AEP_INVISIBLE, flag_EFFECT_INVISIBLE(), has_artifact_with(), Creature::has_effect_with_flag(), has_trait(), is_wearing_active_optcloak(), and trait_DEBUG_CLOAK.

Referenced by visibility().

◆ is_limb_broken()

bool Character::is_limb_broken ( const bodypart_id limb) const

◆ is_limb_disabled()

bool Character::is_limb_disabled ( const bodypart_id limb) const

Returns true if the limb is disabled (12.5% or less hp, or broken)

Definition at line 1257 of file character.cpp.

1258{
1259 return is_limb_broken( limb ) ||
1260 ( get_part_hp_cur( limb ) <= get_part_hp_max( limb ) * 0.125 );
1261}

References Creature::get_part_hp_cur(), Creature::get_part_hp_max(), and is_limb_broken().

Referenced by best_shield(), and get_working_arm_count().

◆ is_max_power()

bool Character::is_max_power ( ) const

Definition at line 1942 of file character.cpp.

1943{
1944 return power_level >= max_power_level;
1945}

References max_power_level, and power_level.

Referenced by feed_furnace_with().

◆ is_mounted()

bool Character::is_mounted ( ) const

Definition at line 1082 of file character.cpp.

1083{
1085}

References effect_riding, Creature::has_effect(), and mounted_creature.

Referenced by activate_bionic(), cata_event_dispatch::avatar_moves(), best_nearby_lifting_assist(), iuse::blood_draw(), iuse::boltcutters(), iuse::burrow(), can_install_bionics(), map::can_move_furniture(), cauterize_actor::can_use(), enzlave_actor::can_use(), musical_instrument_actor::can_use(), install_bionic_actor::can_use(), repair_item_actor::can_use_tool(), can_wield(), iuse::capture_monster_act(), iuse::capture_monster_veh(), debug_menu::character_edit_menu(), check_mount_is_spooked(), check_mount_will_move(), iuse::chop_logs(), iuse::chop_tree(), iuse::clear_rubble(), iuse::craft(), iuse::crowbar(), iuse::cut_log_into_planks(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::disassemble(), dismount(), game::do_turn(), iuse::einktabletpc(), game::examine(), iuse::fill_pit(), ranged::fire_gun(), iuse::fish_trap(), iuse::fishing_rod(), game::grabbed_furn_move(), game::grabbed_veh_move(), iuse::gun_repair(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), iuse::hairkit(), iuse::hammer(), game::handle_action(), has_charges(), iuse::jackhammer(), iuse::ladder(), character_funcs::list_ammo(), iuse::lumber(), iuse::makemound(), iuse::meditate(), melee_attack(), iuse::mind_splicer(), mine_activity(), iuse::mop(), avatar_action::move(), npc::move_to(), game::npc_menu(), game::on_move_effects(), map::open_door(), overmap_sight_range(), iuse::oxytorch(), perform_technique(), iuse::pickaxe(), npc::place_on_map(), game::place_player(), game::place_player_overmap(), avatar_action::plthrow(), iuse::portable_game(), iuse::portal(), game::prompt_dangerous_tile(), recalc_sight_limits(), reset_stats(), iuse::rpgdie(), run_cost(), avatar::set_movement_mode(), iuse::shavekit(), iuse::siphon(), sleep(), smash(), store(), avatar_action::swim(), swim_speed(), iuse::teleport(), ranged::throw_item(), throw_range(), trapfunc::tripwire(), iuse::unfold_generic(), unfold_vehicle_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), cauterize_actor::use(), enzlave_actor::use(), musical_instrument_actor::use(), heal_actor::use(), place_trap_actor::use(), deploy_tent_actor::use(), sew_advanced_actor::use(), weigh_self_actor::use(), use_charges(), game::vertical_move(), iuse::vibe(), game::walk_move(), iuse::wash_hard_items(), wash_items(), iuse::wash_soft_items(), iuse::water_purifier(), weight_capacity(), and npc::worker_downtime().

◆ is_on_ground()

bool Character::is_on_ground ( ) const
overridevirtual

Returns true if the player is knocked over or has broken legs.

Implements Creature.

Definition at line 897 of file character.cpp.

898{
900}

References effect_downed, get_working_leg_count(), and Creature::has_effect().

Referenced by is_immune_field(), map::player_in_field(), and game::walk_move().

◆ is_quiet()

bool Character::is_quiet ( ) const

Returns true if the player has quiet melee attacks.

Definition at line 1222 of file martialarts.cpp.

1223{
1224 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1225 return b.is_quiet();
1226 } );
1227}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by melee_attack().

◆ is_rad_immune()

bool Character::is_rad_immune ( ) const

Returns true if the player is protected from radiation.

Definition at line 6200 of file character.cpp.

6201{
6202 bool has_helmet = false;
6203 return ( is_wearing_power_armor( &has_helmet ) && has_helmet ) || worn_with_flag( "RAD_PROOF" );
6204}

References is_wearing_power_armor(), and worn_with_flag().

Referenced by irradiate(), and suffer_from_radiation().

◆ is_snuggling()

std::string Character::is_snuggling ( ) const

Checks to see if the player is using floor items to keep warm, and return the name of one such item if so.

Definition at line 9332 of file character.cpp.

9333{
9334 map &here = get_map();
9335 auto begin = here.i_at( pos() ).begin();
9336 auto end = here.i_at( pos() ).end();
9337
9338 if( in_vehicle ) {
9339 if( const std::optional<vpart_reference> vp = here.veh_at( pos() ).part_with_feature( VPFLAG_CARGO,
9340 false ) ) {
9341 vehicle *const veh = &vp->vehicle();
9342 const int cargo = vp->part_index();
9343 if( !veh->get_items( cargo ).empty() ) {
9344 begin = veh->get_items( cargo ).begin();
9345 end = veh->get_items( cargo ).end();
9346 }
9347 }
9348 }
9349 const item *floor_armor = nullptr;
9350 int ticker = 0;
9351
9352 // If there are no items on the floor, return nothing
9353 if( begin == end ) {
9354 return "nothing";
9355 }
9356
9357 for( auto candidate = begin; candidate != end; ++candidate ) {
9358 if( !candidate->is_armor() ) {
9359 continue;
9360 } else if( candidate->volume() > 250_ml && candidate->get_warmth() > 0 &&
9361 ( candidate->covers( bp_torso ) || candidate->covers( bp_leg_l ) ||
9362 candidate->covers( bp_leg_r ) ) ) {
9363 floor_armor = &*candidate;
9364 ticker++;
9365 }
9366 }
9367
9368 if( ticker == 0 ) {
9369 return "nothing";
9370 } else if( ticker == 1 ) {
9371 return floor_armor->type_name();
9372 } else if( ticker > 1 ) {
9373 return "many";
9374 }
9375
9376 return "nothing";
9377}
bool in_vehicle
Definition: character.h:1571
bool empty() const
Definition: item_stack.cpp:15

References item_stack::begin(), bp_leg_l, bp_leg_r, bp_torso, item_stack::empty(), item_stack::end(), vehicle::get_items(), get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), in_vehicle, pos(), item::type_name(), vehicle::vehicle(), and VPFLAG_CARGO.

Referenced by fall_asleep().

◆ is_stealthy()

bool Character::is_stealthy ( ) const

Returns true if the player has stealthy movement.

Definition at line 1228 of file martialarts.cpp.

1229{
1230 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1231 return b.is_stealthy();
1232 } );
1233}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by game::walk_move().

◆ is_throw_immune()

bool Character::is_throw_immune ( ) const

Returns true if the player is immune to throws.

Definition at line 1216 of file martialarts.cpp.

1217{
1218 return search_ma_buff_effect( *effects, []( const ma_buff & b, const effect & ) {
1219 return b.is_throw_immune();
1220 } );
1221}

References b, Creature::effects, and search_ma_buff_effect().

Referenced by mattack::bio_op_takedown(), mattack::grab(), is_immune_effect(), mattack::thrown_by_judo(), and game::update_stair_monsters().

◆ is_visible_in_range()

bool Character::is_visible_in_range ( const Creature critter,
int  range 
) const
private

Check whether the other creature is in range and can be seen by this creature.

Parameters
critterCreature to check for visibility
rangeThe maximal distance (rl_dist), creatures at this distance or less are included.

Definition at line 10229 of file character.cpp.

10230{
10231 return sees( critter ) && rl_dist( pos(), critter.pos() ) <= range;
10232}

References Creature::pos(), pos(), range, rl_dist(), and sees().

◆ is_warm()

bool Character::is_warm ( ) const
overridevirtual

Reimplemented from Creature.

Definition at line 534 of file character.cpp.

535{
536 // TODO: is there a mutation (plant?) that makes a npc not warm blooded?
537 return true;
538}

◆ is_waterproof()

bool Character::is_waterproof ( const body_part_set parts) const

Definition at line 9002 of file character.cpp.

9003{
9004 return covered_with_flag( "WATERPROOF", parts );
9005}
bool covered_with_flag(const std::string &flag, const body_part_set &parts) const
Definition: character.cpp:8979

References covered_with_flag().

Referenced by drench().

◆ is_weak_to_water()

bool Character::is_weak_to_water ( ) const

Definition at line 412 of file mutation.cpp.

413{
414 for( const trait_id &mut : get_mutations() ) {
415 if( mut.obj().weakness_to_water > 0 ) {
416 return true;
417 }
418 }
419 return false;
420}

References get_mutations().

Referenced by drench().

◆ is_wearing() [1/2]

◆ is_wearing() [2/2]

bool Character::is_wearing ( const itype_id it) const

Returns true if the player is wearing an item of this type.

Definition at line 3245 of file character.cpp.

3246{
3247 for( auto &i : worn ) {
3248 if( i.typeId() == it ) {
3249 return true;
3250 }
3251 }
3252 return false;
3253}

References worn.

◆ is_wearing_active_optcloak()

bool Character::is_wearing_active_optcloak ( ) const

Returns true if the player is wearing an active optical cloak.

Definition at line 3843 of file character.cpp.

3844{
3845 for( auto &w : worn ) {
3846 if( w.active && w.has_flag( flag_ACTIVE_CLOAKING ) ) {
3847 return true;
3848 }
3849 }
3850 return false;
3851}
static const std::string flag_ACTIVE_CLOAKING("ACTIVE_CLOAKING")

References flag_ACTIVE_CLOAKING(), and worn.

Referenced by basic_symbol_color(), and is_invisible().

◆ is_wearing_active_power_armor()

bool Character::is_wearing_active_power_armor ( ) const

Returns true if the character is wearing active power.

Definition at line 3833 of file character.cpp.

3834{
3835 for( const auto &w : worn ) {
3836 if( w.has_flag( flag_POWERARMOR_EXO ) && w.active ) {
3837 return true;
3838 }
3839 }
3840 return false;
3841}

References flag_POWERARMOR_EXO(), and worn.

◆ is_wearing_helmet()

bool Character::is_wearing_helmet ( ) const

Returns true if the character is wearing something occupying the helmet slot.

Definition at line 8905 of file character.cpp.

8906{
8907 for( const item &i : worn ) {
8908 if( i.covers( bp_head ) && !i.has_flag( flag_HELMET_COMPAT ) && !i.has_flag( flag_SKINTIGHT ) &&
8909 !i.has_flag( flag_PERSONAL ) && !i.has_flag( flag_AURA ) && !i.has_flag( flag_SEMITANGIBLE ) &&
8910 !i.has_flag( flag_OVERSIZE ) ) {
8911 return true;
8912 }
8913 }
8914 return false;
8915}

References bp_head, flag_AURA(), flag_HELMET_COMPAT(), flag_OVERSIZE(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), and worn.

Referenced by can_wear().

◆ is_wearing_on_bp()

bool Character::is_wearing_on_bp ( const itype_id it,
const bodypart_id bp 
) const

Returns true if the player is wearing the item on the given body part.

Definition at line 3255 of file character.cpp.

3256{
3257 for( auto &i : worn ) {
3258 if( i.typeId() == it && i.covers( bp->token ) ) {
3259 return true;
3260 }
3261 }
3262 return false;
3263}

References worn.

Referenced by shoe_type_count().

◆ is_wearing_power_armor()

bool Character::is_wearing_power_armor ( bool *  hasHelmet = nullptr) const

Returns true if the character is wearing power armor.

Definition at line 3808 of file character.cpp.

3809{
3810 bool result = false;
3811 for( auto &elem : worn ) {
3812 if( !elem.is_power_armor() ) {
3813 continue;
3814 }
3815 if( elem.has_flag( flag_POWERARMOR_EXO ) ) {
3816 result = true;
3817 if( hasHelmet == nullptr ) {
3818 // found power armor, helmet not requested, cancel loop
3819 return true;
3820 }
3821 }
3822 // found power armor, continue search for helmet
3823 if( elem.covers( bp_head ) ) {
3824 if( hasHelmet != nullptr ) {
3825 *hasHelmet = true;
3826 }
3827 return true;
3828 }
3829 }
3830 return result;
3831}

References bp_head, flag_POWERARMOR_EXO(), and worn.

Referenced by can_wear(), irradiate(), is_rad_immune(), power_rating(), and suffer_from_radiation().

◆ is_wearing_shoes()

bool Character::is_wearing_shoes ( const side which_side = side::BOTH) const

Returns true if the player is wearing something on their feet that is not SKINTIGHT.

Definition at line 8876 of file character.cpp.

8877{
8878 bool left = true;
8879 bool right = true;
8880 if( which_side == side::LEFT || which_side == side::BOTH ) {
8881 left = false;
8882 for( const item &worn_item : worn ) {
8883 if( worn_item.covers( bp_foot_l ) && !worn_item.has_flag( flag_BELTED ) &&
8884 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8885 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8886 left = true;
8887 break;
8888 }
8889 }
8890 }
8891 if( which_side == side::RIGHT || which_side == side::BOTH ) {
8892 right = false;
8893 for( const item &worn_item : worn ) {
8894 if( worn_item.covers( bp_foot_r ) && !worn_item.has_flag( flag_BELTED ) &&
8895 !worn_item.has_flag( flag_PERSONAL ) && !worn_item.has_flag( flag_AURA ) &&
8896 !worn_item.has_flag( flag_SEMITANGIBLE ) && !worn_item.has_flag( flag_SKINTIGHT ) ) {
8897 right = true;
8898 break;
8899 }
8900 }
8901 }
8902 return ( left && right );
8903}

References BOTH, bp_foot_l, bp_foot_r, flag_AURA(), flag_BELTED(), flag_PERSONAL(), flag_SEMITANGIBLE(), flag_SKINTIGHT(), LEFT, left, RIGHT, right, and worn.

Referenced by can_wear(), rooted_message(), and suffer_from_other_mutations().

◆ is_wielding()

◆ is_worn()

◆ item_encumb()

void Character::item_encumb ( char_encumbrance_data vals,
const item new_item 
) const
protected

Applies encumbrance from items only If new_item is not null, then calculate under the asumption that it is added to existing work items.

Definition at line 3983 of file character.cpp.

3984{
3985
3986 // reset all layer data
3987 vals = char_encumbrance_data();
3988
3989 // Figure out where new_item would be worn
3990 std::list<item>::const_iterator new_item_position = worn.end();
3991 if( !new_item.is_null() ) {
3992 // const_cast required to work around g++-4.8 library bug
3993 // see the commit that added this comment to understand why
3994 new_item_position =
3995 const_cast<Character *>( this )->position_to_wear_new_item( new_item );
3996 }
3997
3998 // Track highest layer observed so far so we can penalize out-of-order
3999 // items
4000 std::array<layer_level, num_bp> highest_layer_so_far;
4001 std::fill( highest_layer_so_far.begin(), highest_layer_so_far.end(),
4003
4004 for( auto w_it = worn.begin(); w_it != worn.end(); ++w_it ) {
4005 if( w_it == new_item_position ) {
4006 layer_item( vals, new_item, highest_layer_so_far, *this );
4007 }
4008 layer_item( vals, *w_it, highest_layer_so_far, *this );
4009 }
4010
4011 if( worn.end() == new_item_position && !new_item.is_null() ) {
4012 layer_item( vals, new_item, highest_layer_so_far, *this );
4013 }
4014
4015 // make sure values are sane
4016 for( const body_part bp : all_body_parts ) {
4017 encumbrance_data &elem = vals.elems[bp];
4018
4019 elem.armor_encumbrance = std::max( 0, elem.armor_encumbrance );
4020
4021 // Add armor and layering penalties for the final values
4022 elem.encumbrance += elem.armor_encumbrance + elem.layer_penalty;
4023 }
4024}
static void layer_item(char_encumbrance_data &vals, const item &it, std::array< layer_level, num_bp > &highest_layer_so_far, const Character &c)
Definition: character.cpp:3766
std::list< item >::iterator position_to_wear_new_item(const item &new_item)
Return the position in the worn list where new_item would be put by default.
Definition: character.cpp:3954
@ PERSONAL_LAYER
Definition: enums.h:216
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
std::array< encumbrance_data, num_bp > elems

References all_body_parts, encumbrance_data::armor_encumbrance, char_encumbrance_data::elems, encumbrance_data::encumbrance, detail::fill(), item::is_null(), layer_item(), encumbrance_data::layer_penalty, PERSONAL_LAYER, position_to_wear_new_item(), and worn.

Referenced by calc_encumbrance().

◆ item_handling_cost()

int Character::item_handling_cost ( const item it,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when handling (e.g.

storing, drawing etc.) an item

Parameters
itItem to calculate handling cost for
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST

Definition at line 7477 of file character.cpp.

7478{
7479 int mv = base_cost;
7480 if( penalties ) {
7481 // 40 moves per liter, up to 200 at 5 liters
7482 mv += std::min( 200, it.volume() / 20_ml );
7483 }
7484
7485 const item &weapon = primary_weapon();
7486 if( weapon.typeId() == itype_e_handcuffs ) {
7487 mv *= 4;
7488 } else if( penalties && has_effect( effect_grabbed ) ) {
7489 mv *= 2;
7490 }
7491
7492 // For single handed items use the least encumbered hand
7493 if( it.is_two_handed( *this ) ) {
7494 mv += encumb( bp_hand_l ) + encumb( bp_hand_r );
7495 } else {
7496 mv += std::min( encumb( bp_hand_l ), encumb( bp_hand_r ) );
7497 }
7498
7499 return std::min( std::max( mv, 0 ), MAX_HANDLING_COST );
7500}
static const itype_id itype_e_handcuffs("e_handcuffs")
static constexpr int MAX_HANDLING_COST

References bp_hand_l, bp_hand_r, effect_grabbed, encumb(), Creature::has_effect(), item::is_two_handed(), itype_e_handcuffs, MAX_HANDLING_COST, primary_weapon(), item::typeId(), and item::volume().

Referenced by dispose_item(), npc::dispose_item(), throw_activity_actor::do_turn(), item_reload_cost(), item_store_cost(), item_wear_cost(), mill_activate(), mill_load_food(), iexamine::quern_examine(), smoker_activate(), smoker_load_food(), iexamine::smoker_options(), character_funcs::try_wield_contents(), avatar_funcs::unload_item(), and avatar::wield().

◆ item_reload_cost()

int Character::item_reload_cost ( const item it,
const item ammo,
int  qty 
) const

Calculate (but do not deduct) the number of moves required to reload an item with specified quantity of ammo.

Parameters
itItem to calculate reload cost for
ammoeither ammo or magazine to use when reloading the item
qtymaximum units of ammo to reload. Capped by remaining capacity and ignored if reloading using a magazine.
Gun decreases the time taken to reload a magazine Pistol decreases time taken to reload a pistol Smg decreases time taken to reload an SMG Rifle decreases time taken to reload a rifle Shotgun decreases time taken to reload a shotgun Launcher decreases time taken to reload a launcher Strength reduces reload time of some weapons

Definition at line 11085 of file character.cpp.

11086{
11087 if( ammo.is_ammo() ) {
11088 qty = std::max( std::min( ammo.charges, qty ), 1 );
11089 } else if( ammo.is_ammo_container() || ammo.is_container() ) {
11090 qty = clamp( qty, ammo.contents.front().charges, 1 );
11091 } else if( ammo.is_magazine() ) {
11092 qty = 1;
11093 } else {
11094 debugmsg( "cannot determine reload cost as %s is neither ammo or magazine", ammo.tname() );
11095 return 0;
11096 }
11097
11098 // If necessary create duplicate with appropriate number of charges
11099 item obj = ammo;
11100 obj = obj.split( qty );
11101 if( obj.is_null() ) {
11102 obj = ammo;
11103 }
11104 // No base cost for handling ammo - that's already included in obtain cost
11105 // We have the ammo in our hands right now
11106 int mv = item_handling_cost( obj, true, 0 );
11107
11108 if( ammo.has_flag( "MAG_BULKY" ) ) {
11109 mv *= 1.5; // bulky magazines take longer to insert
11110 }
11111
11112 if( !it.is_gun() && !it.is_magazine() ) {
11113 return mv + 100; // reload a tool or sealable container
11114 }
11115
11116 /** @EFFECT_GUN decreases the time taken to reload a magazine */
11117 /** @EFFECT_PISTOL decreases time taken to reload a pistol */
11118 /** @EFFECT_SMG decreases time taken to reload an SMG */
11119 /** @EFFECT_RIFLE decreases time taken to reload a rifle */
11120 /** @EFFECT_SHOTGUN decreases time taken to reload a shotgun */
11121 /** @EFFECT_LAUNCHER decreases time taken to reload a launcher */
11122
11123 int cost = ( it.is_gun() ? it.get_reload_time() : it.type->magazine->reload_time ) * qty;
11124
11125 skill_id sk = it.is_gun() ? it.type->gun->skill_used : skill_gun;
11126 mv += cost / ( 1.0f + std::min( get_skill_level( sk ) * 0.1f, 1.0f ) );
11127
11128 if( it.has_flag( "STR_RELOAD" ) ) {
11129 /** @EFFECT_STR reduces reload time of some weapons */
11130 mv -= get_str() * 20;
11131 }
11132
11133 return std::max( mv, 25 );
11134}
static const skill_id skill_gun("gun")
item split(int qty)
Splits a count-by-charges item always leaving source item with minimum of 1 charge.
Definition: item.cpp:726
int get_reload_time() const
Returns the reload time of the gun.
Definition: item.cpp:6538
bool is_magazine() const
Definition: item.cpp:6567
cata::value_ptr< islot_gun > gun
Definition: itype.h:830

References item::charges, clamp(), item::contents, debugmsg, item_contents::front(), item::get_reload_time(), get_skill_level(), get_str(), itype::gun, item::has_flag(), item::is_ammo(), item::is_ammo_container(), item::is_container(), item::is_gun(), item::is_magazine(), item::is_null(), item_handling_cost(), itype::magazine, skill_gun, item::split(), item::tname(), and item::type.

Referenced by npc::do_reload(), npc::enough_time_to_reload(), item_reload_option::moves(), and avatar_funcs::unload_item().

◆ item_store_cost()

int Character::item_store_cost ( const item it,
const item container,
bool  penalties = true,
int  base_cost = INVENTORY_HANDLING_PENALTY 
) const

Calculate (but do not deduct) the number of moves required when storing an item in a container.

Parameters
itItem to calculate storage cost for
containerContainer to store item in
penaltiesWhether item volume and temporary effects (e.g. GRABBED, DOWNED) should be considered.
base_costCost due to storage type.
Returns
cost in moves ranging from 0 to MAX_HANDLING_COST
Pistol decreases time taken to store a pistol Smg decreases time taken to store an SMG Rifle decreases time taken to store a rifle Shotgun decreases time taken to store a shotgun Launcher decreases time taken to store a launcher Stabbing decreases time taken to store a stabbing weapon Cutting decreases time taken to store a cutting weapon Bashing decreases time taken to store a bashing weapon

Definition at line 7502 of file character.cpp.

7504{
7505 /** @EFFECT_PISTOL decreases time taken to store a pistol */
7506 /** @EFFECT_SMG decreases time taken to store an SMG */
7507 /** @EFFECT_RIFLE decreases time taken to store a rifle */
7508 /** @EFFECT_SHOTGUN decreases time taken to store a shotgun */
7509 /** @EFFECT_LAUNCHER decreases time taken to store a launcher */
7510 /** @EFFECT_STABBING decreases time taken to store a stabbing weapon */
7511 /** @EFFECT_CUTTING decreases time taken to store a cutting weapon */
7512 /** @EFFECT_BASHING decreases time taken to store a bashing weapon */
7513 int lvl = get_skill_level( it.is_gun() ? it.gun_skill() : it.melee_skill() );
7514 return item_handling_cost( it, penalties, base_cost ) / ( ( lvl + 10.0f ) / 10.0f );
7515}
skill_id gun_skill() const
The skill used to operate the gun.
Definition: item.cpp:7197

References get_skill_level(), item::gun_skill(), item::is_gun(), item_handling_cost(), and item::melee_skill().

Referenced by dispose_item(), npc::dispose_item(), and character_funcs::store_in_container().

◆ item_wear_cost()

int Character::item_wear_cost ( const item it) const

Calculate (but do not deduct) the number of moves required to wear an item.

Definition at line 7517 of file character.cpp.

7518{
7519 double mv = item_handling_cost( it );
7520
7521 switch( it.get_layer() ) {
7522 case PERSONAL_LAYER:
7523 break;
7524
7525 case UNDERWEAR_LAYER:
7526 mv *= 1.5;
7527 break;
7528
7529 case REGULAR_LAYER:
7530 break;
7531
7532 case WAIST_LAYER:
7533 case OUTER_LAYER:
7534 mv /= 1.5;
7535 break;
7536
7537 case BELTED_LAYER:
7538 mv /= 2.0;
7539 break;
7540
7541 case AURA_LAYER:
7542 break;
7543
7544 default:
7545 break;
7546 }
7547
7548 mv *= std::max( it.get_encumber( *this ) / 10.0, 1.0 );
7549
7550 return mv;
7551}
layer_level get_layer() const
Returns clothing layer for item.
Definition: item.cpp:5885
@ WAIST_LAYER
Definition: enums.h:222
@ UNDERWEAR_LAYER
Definition: enums.h:218
@ REGULAR_LAYER
Definition: enums.h:220
@ BELTED_LAYER
Definition: enums.h:226
@ AURA_LAYER
Definition: enums.h:228
@ OUTER_LAYER
Definition: enums.h:224

References AURA_LAYER, BELTED_LAYER, item::get_encumber(), item::get_layer(), item_handling_cost(), OUTER_LAYER, PERSONAL_LAYER, REGULAR_LAYER, UNDERWEAR_LAYER, and WAIST_LAYER.

Referenced by dispose_item(), and wear_item().

◆ item_with_best_of_quality()

item & Character::item_with_best_of_quality ( const quality_id qid)

Returns the item in the player's inventory with the highest of the specified quality.

Definition at line 10017 of file character.cpp.

10018{
10019 int maxq = max_quality( qid );
10020 auto items_with_quality = items_with( [qid]( const item & it ) {
10021 return it.has_quality( qid );
10022 } );
10023 for( item *it : items_with_quality ) {
10024 if( it->get_quality( qid ) == maxq ) {
10025 return *it;
10026 }
10027 }
10028 return null_item_reference();
10029}
int get_quality(const quality_id &id) const
Definition: item.cpp:5410

References item::get_quality(), visitable< T >::has_quality(), visitable< Character >::items_with(), visitable< Character >::max_quality(), and null_item_reference().

◆ item_worn_with_flag()

const item * Character::item_worn_with_flag ( const std::string &  flag,
const bodypart_id bp = bodypart_str_id::NULL_ID() 
) const

Returns the first worn item with a given flag.

Definition at line 3273 of file character.cpp.

3274{
3275 for( const item &it : worn ) {
3276 if( it.has_flag( flag ) && ( bp == bodypart_str_id::NULL_ID() ||
3277 it.covers( bp->token ) ) ) {
3278 return &it;
3279 }
3280 }
3281 return nullptr;
3282}

References string_id< body_part_type >::NULL_ID(), and worn.

Referenced by burn_fuel().

◆ knock_back_to()

void Character::knock_back_to ( const tripoint to)
overridevirtual

Knocks the character to a specified tile.

Maximum Strength allows knocked back player to knock back, damage, stun some monsters

Implements Creature.

Definition at line 10973 of file character.cpp.

10974{
10975 if( to == pos() ) {
10976 return;
10977 }
10978
10979 if( rl_dist( pos(), to ) < 2 && get_map().obstructed_by_vehicle_rotation( pos(), to ) ) {
10980 tripoint intervening = to;
10981 if( one_in( 2 ) ) {
10982 intervening.x = pos().x;
10983 } else {
10984 intervening.y = pos().y;
10985 }
10986
10987 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
10988 add_effect( effect_stunned, 2_turns );
10989 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
10990 g->m.obstacle_name( intervening ) );
10991 return;
10992 }
10993
10994 // First, see if we hit a monster
10995 if( monster *const critter = g->critter_at<monster>( to ) ) {
10996 deal_damage( critter, bodypart_id( "torso" ), damage_instance( DT_BASH, critter->type->size ) );
10997 add_effect( effect_stunned, 1_turns );
10998 /** @EFFECT_STR_MAX allows knocked back player to knock back, damage, stun some monsters */
10999 if( ( str_max - 6 ) / 4 > critter->type->size ) {
11000 critter->knock_back_from( pos() ); // Chain reaction!
11001 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
11002 critter->add_effect( effect_stunned, 1_turns );
11003 } else if( ( str_max - 6 ) / 4 == critter->type->size ) {
11004 critter->apply_damage( this, bodypart_id( "torso" ), ( str_max - 6 ) / 4 );
11005 critter->add_effect( effect_stunned, 1_turns );
11006 }
11007 critter->check_dead_state();
11008
11009 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
11010 critter->name() );
11011 return;
11012 }
11013
11014 if( npc *const np = g->critter_at<npc>( to ) ) {
11015 deal_damage( np, bodypart_id( "torso" ), damage_instance( DT_BASH, np->get_size() + 1 ) );
11016 add_effect( effect_stunned, 1_turns );
11017 np->deal_damage( this, bodypart_id( "torso" ), damage_instance( DT_BASH, 3 ) );
11018 add_msg_player_or_npc( _( "You bounce off %s!" ), _( "<npcname> bounces off %s!" ),
11019 np->name );
11020 np->check_dead_state();
11021 return;
11022 }
11023
11024 // If we're still in the function at this point, we're actually moving a tile!
11025 if( g->m.has_flag( "LIQUID", to ) && g->m.has_flag( TFLAG_DEEP_WATER, to ) ) {
11026 if( !is_npc() ) {
11027 avatar_action::swim( g->m, g->u, to );
11028 }
11029 // TODO: NPCs can't swim!
11030 } else if( g->m.impassable( to ) ) { // Wait, it's a wall
11031
11032 // It's some kind of wall.
11033 // TODO: who knocked us back? Maybe that creature should be the source of the damage?
11034 apply_damage( nullptr, bodypart_id( "torso" ), 3 );
11035 add_effect( effect_stunned, 2_turns );
11036 add_msg_player_or_npc( _( "You bounce off a %s!" ), _( "<npcname> bounces off a %s!" ),
11037 g->m.obstacle_name( to ) );
11038
11039 } else { // It's no wall
11040 setpos( to );
11041
11042 map &here = get_map();
11043 here.creature_on_trap( *this );
11044 }
11045}
@ TFLAG_DEEP_WATER
Definition: mapdata.h:302
void swim(map &m, avatar &you, const tripoint &p)
Handles swimming by the player.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), apply_damage(), deal_damage(), DT_BASH, effect_stunned, g, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), Creature::is_npc(), one_in(), pos(), rl_dist(), setpos(), str_max, avatar_action::swim(), TFLAG_DEEP_WATER, tripoint::x, and tripoint::y.

◆ knows_recipe()

bool Character::knows_recipe ( const recipe rec) const

Definition at line 10601 of file character.cpp.

10602{
10603 return get_learned_recipes().contains( *rec );
10604}
const recipe_subset & get_learned_recipes() const
Returns all known recipes.
bool contains(const recipe &r) const
Check if the subset contains a recipe with the specified id.

References recipe_subset::contains(), and get_learned_recipes().

Referenced by npc::add_msg_player_or_npc(), item::book_info(), complete_craft(), crafting::complete_disassemble(), avatar::create(), avatar::do_read(), find_repair_difficulty(), read_inventory_preset::get_known_recipes(), player::has_recipe(), select_crafting_recipe(), conditional_t< T >::set_u_know_recipe(), and skim_book_msg().

◆ knows_trap()

bool Character::knows_trap ( const tripoint pos) const

Definition at line 10253 of file character.cpp.

10254{
10255 const tripoint p = get_map().getabs( pos );
10256 return known_traps.count( p ) > 0;
10257}

References get_map(), map::getabs(), known_traps, and pos().

Referenced by trap::can_see(), vehicle::handle_trap(), and character_funcs::search_surroundings().

◆ leak_level()

int Character::leak_level ( const std::string &  flag) const

Definition at line 1922 of file suffer.cpp.

1923{
1924 int leak_level = 0;
1925 leak_level = inv.leak_level( flag );
1926 return leak_level;
1927}
int leak_level(const std::string &flag) const
Definition: suffer.cpp:1922
int leak_level(const std::string &flag) const
Definition: inventory.cpp:900

References inv, leak_level(), and inventory::leak_level().

Referenced by iexamine::autodoc(), iuse::geiger(), leak_level(), and suffer_from_radiation().

◆ learn_recipe()

void Character::learn_recipe ( const recipe rec)

Definition at line 10606 of file character.cpp.

10607{
10608 if( rec->never_learn ) {
10609 return;
10610 }
10611 learned_recipes->include( rec );
10612}
bool never_learn
Prevent this recipe from ever being added to the player's learned recipies ( used for special NPC cra...
Definition: recipe.h:93

References learned_recipes, and recipe::never_learn.

Referenced by debug_menu::character_edit_menu(), complete_craft(), crafting::complete_disassemble(), avatar::create(), and avatar::do_read().

◆ limb_color()

nc_color Character::limb_color ( const bodypart_id bp,
bool  bleed,
bool  bite,
bool  infect 
) const

Definition at line 5966 of file character.cpp.

5967{
5968 if( bp == bodypart_id( "num_bp" ) ) {
5969 return c_light_gray;
5970 }
5971 const body_part bp_token = bp->token;
5972 int color_bit = 0;
5973 nc_color i_color = c_light_gray;
5974 if( bleed && has_effect( effect_bleed, bp_token ) ) {
5975 color_bit += 1;
5976 }
5977 if( bite && has_effect( effect_bite, bp_token ) ) {
5978 color_bit += 10;
5979 }
5980 if( infect && has_effect( effect_infected, bp_token ) ) {
5981 color_bit += 100;
5982 }
5983 switch( color_bit ) {
5984 case 1:
5985 i_color = c_red;
5986 break;
5987 case 10:
5988 i_color = c_blue;
5989 break;
5990 case 100:
5991 i_color = c_green;
5992 break;
5993 case 11:
5994 i_color = c_magenta;
5995 break;
5996 case 101:
5997 i_color = c_yellow;
5998 break;
5999 }
6000
6001 return i_color;
6002}

References Creature::bleed(), c_blue, c_green, c_light_gray, c_magenta, c_red, c_yellow, effect_bite, effect_bleed, effect_infected, and Creature::has_effect().

Referenced by body_window(), draw_health_classic(), draw_limb2(), draw_limb_narrow(), draw_limb_wide(), and extended_description().

◆ load()

void Character::load ( const JsonObject data)
protected

Gather variables for saving.

These variables are common to both the avatar and NPCs.

Definition at line 388 of file savegame_json.cpp.

389{
391 Creature::load( data );
392
393 if( !data.read( "posx", position.x ) ) { // uh-oh.
394 debugmsg( "BAD PLAYER/NPC JSON: no 'posx'?" );
395 }
396 data.read( "posy", position.y );
397 if( !data.read( "posz", position.z ) && g != nullptr ) {
398 position.z = g->get_levz();
399 }
400 // stats
401 data.read( "str_cur", str_cur );
402 data.read( "str_max", str_max );
403 data.read( "dex_cur", dex_cur );
404 data.read( "dex_max", dex_max );
405 data.read( "int_cur", int_cur );
406 data.read( "int_max", int_max );
407 data.read( "per_cur", per_cur );
408 data.read( "per_max", per_max );
409
410 data.read( "str_bonus", str_bonus );
411 data.read( "dex_bonus", dex_bonus );
412 data.read( "per_bonus", per_bonus );
413 data.read( "int_bonus", int_bonus );
414 data.read( "omt_path", omt_path );
415
416 std::string new_name;
417 data.read( "name", new_name );
418 if( !new_name.empty() ) {
419 // Bugfix for name not having been saved properly
420 name = new_name;
421 }
422
423 data.read( "base_age", init_age );
424 data.read( "base_height", init_height );
425
426 if( !data.read( "profession", prof ) || !prof.is_valid() ) {
427 // We are likely an older profession which has since been removed so just set to default.
428 // This is only cosmetic after game start.
430 }
431 data.read( "custom_profession", custom_profession );
432
433 // needs
434 data.read( "thirst", thirst );
435 data.read( "fatigue", fatigue );
436 data.read( "sleep_deprivation", sleep_deprivation );
437 data.read( "stored_calories", stored_calories );
438 data.read( "radiation", radiation );
439 data.read( "oxygen", oxygen );
440 data.read( "pkill", pkill );
441
442 data.read( "type_of_scent", type_of_scent );
443
444 if( data.has_array( "ma_styles" ) ) {
445 std::vector<matype_id> temp_styles;
446 data.read( "ma_styles", temp_styles );
447 bool temp_keep_hands_free = false;
448 data.read( "keep_hands_free", temp_keep_hands_free );
449 matype_id temp_selected_style;
450 data.read( "style_selected", temp_selected_style );
451 if( !temp_selected_style.is_valid() ) {
452 temp_selected_style = matype_id( "style_none" );
453 }
455 temp_styles, temp_selected_style, temp_keep_hands_free
456 ) );
457 } else {
458 data.read( "martial_arts_data", martial_arts_data );
459 }
460
461 JsonObject vits = data.get_object( "vitamin_levels" );
463 for( const std::pair<const vitamin_id, vitamin> &v : vitamin::all() ) {
464 if( vits.has_member( v.first.str() ) ) {
465 int lvl = vits.get_int( v.first.str() );
466 vitamin_levels[v.first] = clamp( lvl, v.first->min(), v.first->max() );
467 }
468 }
469 data.read( "consumption_history", consumption_history );
470 data.read( "activity", activity );
471 data.read( "destination_activity", destination_activity );
472 data.read( "stashed_outbounds_activity", stashed_outbounds_activity );
473 data.read( "stashed_outbounds_backlog", stashed_outbounds_backlog );
474 data.read( "backlog", backlog );
475 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
476 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
477 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
478 requirement_data fetch_reqs;
479 data.read( "fetch_data", fetch_reqs );
480 const requirement_id req_id( backlog.front().str_values.back() );
481 requirement_data::save_requirement( fetch_reqs, req_id );
482 }
483 // npc activity on vehicles.
484 data.read( "activity_vehicle_part_index", activity_vehicle_part_index );
485 // health
486 data.read( "healthy", healthy );
487 data.read( "healthy_mod", healthy_mod );
488 data.read( "healed_24h", healed_total );
489
490 // status
491 temp_cur.fill( 5000 );
492 data.read( "temp_cur", temp_cur );
493
494 temp_conv.fill( 5000 );
495 data.read( "temp_conv", temp_conv );
496
497 frostbite_timer.fill( 0 );
498 data.read( "frostbite_timer", frostbite_timer );
499
500 body_wetness.fill( 0 );
501 data.read( "body_wetness", body_wetness );
502
503 //energy
504 data.read( "stim", stim );
505 data.read( "stamina", stamina );
506
507 data.read( "damage_bandaged", damage_bandaged );
508 data.read( "damage_disinfected", damage_disinfected );
509 data.read( "magic", magic );
510 JsonArray parray;
511
512 data.read( "traits", my_traits );
513 for( auto it = my_traits.begin(); it != my_traits.end(); ) {
514 const auto &tid = *it;
515 if( tid.is_valid() ) {
516 ++it;
517 } else {
518 debugmsg( "character %s has invalid trait %s, it will be ignored", name, tid.c_str() );
519 my_traits.erase( it++ );
520 }
521 }
522
523 data.read( "mutations", my_mutations );
524 for( auto it = my_mutations.begin(); it != my_mutations.end(); ) {
525 const trait_id &mid = it->first;
526 if( mid.is_valid() ) {
527 on_mutation_gain( mid );
528 cached_mutations.push_back( &mid.obj() );
529 ++it;
530 } else {
531 debugmsg( "character %s has invalid mutation %s, it will be ignored", name, mid.c_str() );
532 it = my_mutations.erase( it );
533 }
534 }
536
537 data.read( "my_bionics", *my_bionics );
538
539 for( auto &w : worn ) {
540 w.on_takeoff( *this );
541 }
542 worn.clear();
543 data.read( "worn", worn );
544 for( auto &w : worn ) {
545 on_item_wear( w );
546 }
547
548 if( data.has_array( "hp_cur" ) ) {
549 set_anatomy( anatomy_id( "human_anatomy" ) );
550 set_body();
551 std::array<int, 6> hp_cur;
552 data.read( "hp_cur", hp_cur );
553 std::array<int, 6> hp_max;
554 data.read( "hp_max", hp_max );
555 set_part_hp_max( bodypart_id( "head" ), hp_max[0] );
556 set_part_hp_cur( bodypart_id( "head" ), hp_cur[0] );
557
558 set_part_hp_max( bodypart_id( "torso" ), hp_max[1] );
559 set_part_hp_cur( bodypart_id( "torso" ), hp_cur[1] );
560
561 set_part_hp_max( bodypart_id( "arm_l" ), hp_max[2] );
562 set_part_hp_cur( bodypart_id( "arm_l" ), hp_cur[2] );
563
564 set_part_hp_max( bodypart_id( "arm_r" ), hp_max[3] );
565 set_part_hp_cur( bodypart_id( "arm_r" ), hp_cur[3] );
566
567 set_part_hp_max( bodypart_id( "leg_l" ), hp_max[4] );
568 set_part_hp_cur( bodypart_id( "leg_l" ), hp_cur[4] );
569
570 set_part_hp_max( bodypart_id( "leg_r" ), hp_max[5] );
571 set_part_hp_cur( bodypart_id( "leg_r" ), hp_cur[5] );
572 }
573
574
575 inv.clear();
576 if( data.has_member( "inv" ) ) {
577 JsonIn *invin = data.get_raw( "inv" );
578 inv.json_load_items( *invin );
579 }
580
582 data.read( "weapon", primary_weapon() );
583
584 data.read( "move_mode", move_mode );
585
586 if( has_effect( effect_riding ) ) {
587 int temp_id;
588 if( data.read( "mounted_creature", temp_id ) ) {
589 mounted_creature_id = temp_id;
590 mounted_creature = g->critter_tracker->from_temporary_id( temp_id );
591 } else {
592 mounted_creature = nullptr;
593 }
594 }
595
596 morale->load( data );
597 // Have to go through effects again, in case an effect gained a morale bonus
598 for( const auto &elem : *effects ) {
599 for( const std::pair<const bodypart_str_id, effect> &_effect_it : elem.second ) {
600 const effect &e = _effect_it.second;
602 }
603 }
604
605 _skills->clear();
606 for( const JsonMember member : data.get_object( "skills" ) ) {
607 member.read( ( *_skills )[skill_id( member.name() )] );
608 }
609
610 data.read( "learned_recipes", *learned_recipes );
611 autolearn_skills_stamp->clear(); // Invalidates the cache
612
613 on_stat_change( "thirst", thirst );
614 on_stat_change( "stored_calories", stored_calories );
615 on_stat_change( "fatigue", fatigue );
616 on_stat_change( "sleep_deprivation", sleep_deprivation );
617 on_stat_change( "pkill", pkill );
618 on_stat_change( "perceived_pain", get_perceived_pain() );
621
622 assign( data, "power_level", power_level, false, 0_kJ );
623 assign( data, "max_power_level", max_power_level, false, 0_kJ );
624
625 // Bionic power should not be negative!
626 if( power_level < 0_J ) {
627 power_level = 0_J;
628 }
629
630 JsonArray overmap_time_array = data.get_array( "overmap_time" );
631 overmap_time.clear();
632 while( overmap_time_array.has_more() ) {
633 point_abs_omt pt;
634 overmap_time_array.read_next( pt );
635 time_duration tdr = 0_turns;
636 overmap_time_array.read_next( tdr );
637 overmap_time[pt] = tdr;
638 }
639 data.read( "stomach", stomach );
640 data.read( "automoveroute", auto_move_route );
641
642 known_traps.clear();
643 for( JsonObject pmap : data.get_array( "known_traps" ) ) {
644 pmap.allow_omitted_members();
645 const tripoint p( pmap.get_int( "x" ), pmap.get_int( "y" ), pmap.get_int( "z" ) );
646 const std::string t = pmap.get_string( "trap" );
647 known_traps.insert( trap_map::value_type( p, t ) );
648 }
649}
bool assign(const JsonObject &jo, const std::string &name, bool &val, bool strict)
Definition: assign.cpp:16
void on_stat_change(const std::string &stat, int value) override
Called when a stat is changed.
Definition: character.cpp:9916
std::map< vitamin_id, int > vitamin_levels
Current deficiency/excess quantity for each vitamin.
Definition: character.h:2204
int activity_vehicle_part_index
Definition: character.h:1619
void on_effect_int_change(const efftype_id &effect_type, int intensity, const bodypart_str_id &bp) override
Called when effect intensity has been changed.
Definition: character.cpp:9887
int oxygen
Definition: character.h:1591
void on_item_wear(const item &it)
Called when an item is worn.
Definition: character.cpp:9859
void recalculate_size()
Recalculate size class of character.
Definition: mutation.cpp:244
int mounted_creature_id
Definition: character.h:1617
void set_part_hp_max(const bodypart_id &id, int set)
Definition: creature.cpp:1627
void load(const JsonObject &jsin)
bool has_more() const
Definition: json.cpp:552
bool read_next(T &t)
Definition: json.h:1112
Definition: json.h:172
Represents a member of a JsonObject.
Definition: json.h:1249
JsonObject get_object(const std::string &name) const
Definition: json.cpp:429
JsonArray get_array(const std::string &name) const
Definition: json.cpp:400
bool has_member(const std::string &name) const
Definition: json.cpp:182
JsonIn * get_raw(const std::string &name) const
Definition: json.cpp:309
int get_int(const std::string &name) const
Definition: json.cpp:350
bool has_array(const std::string &name) const
Definition: json.cpp:483
void allow_omitted_members() const
Definition: json.cpp:151
bool read(const std::string &name, T &t, bool throw_on_error=true) const
Definition: json.h:941
void json_load_items(JsonIn &jsin)
void clear()
Definition: inventory.cpp:239
This is a wrapper for implementing the pointer-to-implementation technique, see for example http://en...
Definition: pimpl.h:35
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:255
static const std::map< vitamin_id, vitamin > & all()
Get all currently loaded vitamins.
Definition: vitamin.cpp:98
std::string member
Definition: mapgen.cpp:419
static const efftype_id effect_riding("riding")
static void save_requirement(const requirement_data &req, const requirement_id &id=requirement_id::NULL_ID())
Store requirement data for future lookup.

References _skills, activity, activity_vehicle_part_index, vitamin::all(), JsonObject::allow_omitted_members(), assign(), auto_move_route, autolearn_skills_stamp, backlog, body_wetness, string_id< T >::c_str(), cached_mutations, clamp(), inventory::clear(), consumption_history, custom_profession, damage_bandaged, damage_disinfected, debugmsg, destination_activity, dex_bonus, dex_cur, dex_max, effect_riding, Creature::effects, fatigue, frostbite_timer, g, profession::generic(), JsonObject::get_array(), effect::get_bp(), effect::get_id(), JsonObject::get_int(), effect::get_intensity(), JsonObject::get_object(), get_perceived_pain(), JsonObject::get_raw(), JsonObject::has_array(), Creature::has_effect(), JsonObject::has_member(), JsonArray::has_more(), healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, inv, string_id< T >::is_valid(), inventory::json_load_items(), known_traps, learned_recipes, Creature::load(), magic, martial_arts_data, matype_id, max_power_level, mapgen_defer::member, morale, mounted_creature, mounted_creature_id, move_mode, my_bionics, my_mutations, my_traits, name, string_id< T >::obj(), omt_path, on_effect_int_change(), on_item_wear(), on_mutation_gain(), on_stat_change(), overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, primary_weapon(), prof, radiation, JsonObject::read(), JsonArray::read_next(), recalc_sight_limits(), recalculate_size(), reset_encumbrance(), requirement_data::save_requirement(), Creature::set_anatomy(), Creature::set_body(), Creature::set_part_hp_cur(), Creature::set_part_hp_max(), set_primary_weapon(), skill_id, sleep_deprivation, stamina, calendar::start_of_cataclysm, stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, type_of_scent, vitamin_levels, worn, tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::load().

◆ mabuff_armor_bonus()

int Character::mabuff_armor_bonus ( damage_type  type) const

Returns the armor bonus against given type from martial arts buffs.

Definition at line 1170 of file martialarts.cpp.

1171{
1172 int ret = 0;
1173 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1174 ret += d.get_intensity() * b.armor_bonus( *this, type );
1175 } );
1176 return ret;
1177}
static void accumulate_ma_buff_effects(const C &container, F f)

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by passive_absorb_hit().

◆ mabuff_arpen_bonus()

int Character::mabuff_arpen_bonus ( damage_type  type) const

Returns the arpen bonus from martial arts buffs.

Definition at line 1162 of file martialarts.cpp.

1163{
1164 int ret = 0;
1165 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1166 ret += d.get_intensity() * b.arpen_bonus( *this, type );
1167 } );
1168 return ret;
1169}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_attack_cost_mult()

float Character::mabuff_attack_cost_mult ( ) const

Returns the multiplier on move cost of attacks.

Definition at line 1204 of file martialarts.cpp.

1205{
1206 float ret = 1.0f;
1207 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1208 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1209 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1210 ret *= d.get_intensity() * ( b.bonuses.get_mult( *this,
1211 affected_stat::MOVE_COST ) - 1 ) + 1;
1212 } );
1213 return ret;
1214}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_attack_cost_penalty()

int Character::mabuff_attack_cost_penalty ( ) const

Returns the flat penalty to move cost of attacks.

If negative, that's a bonus. Applied after multiplier.

Definition at line 1196 of file martialarts.cpp.

1197{
1198 int ret = 0;
1199 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1200 ret += d.get_intensity() * b.bonuses.get_flat( *this, affected_stat::MOVE_COST );
1201 } );
1202 return ret;
1203}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), MOVE_COST, and cata::hash64_detail::ret.

Referenced by attack_cost().

◆ mabuff_block_bonus()

int Character::mabuff_block_bonus ( ) const

Returns the block bonus from martial arts buffs.

Definition at line 1146 of file martialarts.cpp.

1147{
1148 int ret = 0;
1149 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1150 ret += d.get_intensity() * b.block_bonus( *this );
1151 } );
1152 return ret;
1153}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by block_hit().

◆ mabuff_damage_bonus()

int Character::mabuff_damage_bonus ( damage_type  type) const

Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.

Definition at line 1188 of file martialarts.cpp.

1189{
1190 int ret = 0;
1191 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1192 ret += d.get_intensity() * b.damage_bonus( *this, type );
1193 } );
1194 return ret;
1195}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_damage_mult()

float Character::mabuff_damage_mult ( damage_type  type) const

Returns the damage multiplier to given type from martial arts buffs.

Definition at line 1178 of file martialarts.cpp.

1179{
1180 float ret = 1.f;
1181 accumulate_ma_buff_effects( *effects, [&ret, type, this]( const ma_buff & b, const effect & d ) {
1182 // This is correct, so that a 20% buff (1.2) plus a 20% buff (1.2)
1183 // becomes 1.4 instead of 2.4 (which would be a 240% buff)
1184 ret *= d.get_intensity() * ( b.damage_mult( *this, type ) - 1 ) + 1;
1185 } );
1186 return ret;
1187}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), cata::hash64_detail::ret, and type.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ mabuff_dodge_bonus()

float Character::mabuff_dodge_bonus ( ) const

Returns the dodge bonus from martial arts buffs.

Definition at line 1138 of file martialarts.cpp.

1139{
1140 float ret = 0;
1141 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1142 ret += d.get_intensity() * b.dodge_bonus( *this );
1143 } );
1144 return ret;
1145}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by reset_stats().

◆ mabuff_speed_bonus()

int Character::mabuff_speed_bonus ( ) const

Returns the speed bonus from martial arts buffs.

Definition at line 1154 of file martialarts.cpp.

1155{
1156 int ret = 0;
1157 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & d ) {
1158 ret += d.get_intensity() * b.speed_bonus( *this );
1159 } );
1160 return ret;
1161}

References accumulate_ma_buff_effects(), b, Creature::effects, effect::get_intensity(), and cata::hash64_detail::ret.

Referenced by recalc_speed_bonus().

◆ mabuff_tohit_bonus()

float Character::mabuff_tohit_bonus ( ) const

Returns the to hit bonus from martial arts buffs.

Definition at line 1130 of file martialarts.cpp.

1131{
1132 float ret = 0;
1133 accumulate_ma_buff_effects( *effects, [&ret, this]( const ma_buff & b, const effect & ) {
1134 ret += b.hit_bonus( *this );
1135 } );
1136 return ret;
1137}

References accumulate_ma_buff_effects(), b, Creature::effects, and cata::hash64_detail::ret.

Referenced by get_melee_hit_base().

◆ made_of()

bool Character::made_of ( const material_id m) const
overridevirtual

Implements Creature.

Definition at line 6252 of file character.cpp.

6253{
6254 // TODO: check for mutations that change this.
6255 return std::find( fleshy.begin(), fleshy.end(), m ) != fleshy.end();
6256}
static const std::vector< material_id > fleshy
Definition: character.h:784

References detail::find(), and fleshy.

Referenced by block_hit().

◆ made_of_any()

bool Character::made_of_any ( const std::set< material_id > &  ms) const
overridevirtual

Implements Creature.

Definition at line 6257 of file character.cpp.

6258{
6259 // TODO: check for mutations that change this.
6260 return std::any_of( fleshy.begin(), fleshy.end(), [&ms]( const material_id & e ) {
6261 return ms.count( e );
6262 } );
6263}
constexpr scale ms
Definition: coordinates.h:30

References fleshy, and coords::ms.

◆ max_stored_kcal()

◆ meets_requirements()

bool Character::meets_requirements ( const item it,
const item context = item() 
) const

Checks whether the character meets overall requirements to be able to use the item.

Definition at line 3543 of file character.cpp.

3544{
3545 const auto &ctx = !context.is_null() ? context : it;
3547}
bool meets_stat_requirements(const item &it) const
Checks whether the character's stats meets the stats required by the item.
Definition: character.cpp:3535

References item::is_null(), meets_skill_requirements(), meets_stat_requirements(), itype::min_skills, and item::type.

Referenced by can_use(), gunmod_inventory_preset::get_denial(), and item::gun_range().

◆ meets_skill_requirements() [1/2]

bool Character::meets_skill_requirements ( const construction con) const

Checks whether the character's skills meet the required.

Definition at line 3527 of file character.cpp.

3528{
3529 return std::all_of( con.required_skills.begin(), con.required_skills.end(),
3530 [&]( const std::pair<skill_id, int> &pr ) {
3531 return get_skill_level( pr.first ) >= pr.second;
3532 } );
3533}
std::map< skill_id, int > required_skills
Skill->skill level mapping.
Definition: construction.h:72

References construction::required_skills.

◆ meets_skill_requirements() [2/2]

bool Character::meets_skill_requirements ( const std::map< skill_id, int > &  req,
const item context = item() 
) const

Checks whether the character's skills meet the required.

Definition at line 3521 of file character.cpp.

3523{
3524 return _skills->meets_skill_requirements( req, context );
3525}

References _skills.

Referenced by activity_handlers::build_do_turn(), can_learn_by_disassembly(), find_base_construction(), get_learned_recipes(), meets_requirements(), and player_can_build().

◆ meets_stat_requirements()

bool Character::meets_stat_requirements ( const item it) const

Checks whether the character's stats meets the stats required by the item.

Definition at line 3535 of file character.cpp.

3536{
3537 return ( it.has_flag( flag_STR_DRAW ) || get_str() >= it.get_min_str() ) &&
3538 get_dex() >= it.type->min_dex &&
3539 get_int() >= it.type->min_int &&
3540 get_per() >= it.type->min_per;
3541}
static const std::string flag_STR_DRAW("STR_DRAW")

References flag_STR_DRAW(), get_dex(), get_int(), item::get_min_str(), get_per(), get_str(), item::has_flag(), itype::min_dex, itype::min_int, itype::min_per, and item::type.

Referenced by meets_requirements().

◆ melee_attack()

void Character::melee_attack ( Creature t,
bool  allow_special,
const matec_id force_technique = nullptr,
bool  allow_unarmed = true 
)

Sets up a melee attack and handles melee attack function calls.

Parameters
tCreature to attack
allow_specialwhether non-forced martial art technique or mutation attack should be possible with this attack.
force_techniquespecial technique to use in attack (leave as nullptr to use random technique).
allow_unarmedalways uses the wielded weapon regardless of martialarts style
Melee andStrength reduce stamina cost of melee attacks

Definition at line 445 of file melee.cpp.

447{
449 int hit_spread = t.deal_melee_attack( this, hit_roll() );
450 if( !t.is_player() ) {
451 // TODO: Per-NPC tracking? Right now monster hit by either npc or player will draw aggro...
452 t.add_effect( effect_hit_by_player, 10_minutes ); // Flag as attacked by us for AI
453 }
454 if( is_mounted() ) {
455 auto mons = mounted_creature.get();
456 if( mons->has_flag( MF_RIDEABLE_MECH ) ) {
457 if( !mons->check_mech_powered() ) {
458 add_msg( m_bad, _( "The %s has dead batteries and will not move its arms." ),
459 mons->get_name() );
460 return;
461 }
462 if( mons->type->has_special_attack( "SMASH" ) && one_in( 3 ) ) {
463 add_msg( m_info, _( "The %s hisses as its hydraulic arm pumps forward!" ),
464 mons->get_name() );
465 mattack::smash_specific( mons, &t );
466 } else {
467 mons->use_mech_power( -2 );
468 mons->melee_attack( t );
469 }
470 mod_moves( -mons->type->attack_cost );
471 return;
472 }
473 }
474 item &cur_weapon = allow_unarmed ? used_weapon() : primary_weapon();
475
476 if( cur_weapon.attack_cost() > attack_cost( cur_weapon ) * 20 ) {
477 add_msg( m_bad, _( "This weapon is too unwieldy to attack with!" ) );
478 return;
479 }
480
481 int move_cost = attack_cost( cur_weapon );
482
483 if( hit_spread < 0 ) {
484 int stumble_pen = stumble( *this, cur_weapon );
485 sfx::generate_melee_sound( pos(), t.pos(), false, false );
486 if( is_player() ) { // Only display messages if this is the player
487
488 if( one_in( 2 ) ) {
489 const std::string reason_for_miss = get_miss_reason();
490 if( !reason_for_miss.empty() ) {
491 add_msg( reason_for_miss );
492 }
493 }
494
495 if( can_miss_recovery( cur_weapon ) ) {
496 ma_technique tec = martial_arts_data->get_miss_recovery_tec( cur_weapon );
497 add_msg( _( tec.avatar_message ), t.disp_name() );
498 } else if( stumble_pen >= 60 ) {
499 add_msg( m_bad, _( "You miss and stumble with the momentum." ) );
500 } else if( stumble_pen >= 10 ) {
501 add_msg( _( "You swing wildly and miss." ) );
502 } else {
503 add_msg( _( "You miss." ) );
504 }
505 } else if( g->u.sees( *this ) ) {
506 if( stumble_pen >= 60 ) {
507 add_msg( _( "%s misses and stumbles with the momentum." ), name );
508 } else if( stumble_pen >= 10 ) {
509 add_msg( _( "%s swings wildly and misses." ), name );
510 } else {
511 add_msg( _( "%s misses." ), name );
512 }
513 }
514
515 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
516 if( !has_active_bionic( bio_cqb ) ) {
517 melee_train( *this, 2, 5, cur_weapon );
518 }
519
520 // Cap stumble penalty, heavy weapons are quite weak already
521 move_cost += std::min( 60, stumble_pen );
522 if( martial_arts_data->has_miss_recovery_tec( cur_weapon ) ) {
523 move_cost /= 2;
524 }
525
526 // trigger martial arts on-miss effects
527 martial_arts_data->ma_onmiss_effects( *this );
528 } else {
530 // Remember if we see the monster at start - it may change
531 const bool seen = g->u.sees( t );
532 // Start of attacks.
533 const bool critical_hit = scored_crit( t.dodge_roll(), cur_weapon );
534 if( critical_hit ) {
536 }
538 roll_all_damage( critical_hit, d, false, cur_weapon );
539
540 const bool has_force_technique = force_technique;
541
542 // Pick one or more special attacks
543 matec_id technique_id;
544 if( allow_special && !has_force_technique ) {
545 technique_id = pick_technique( t, cur_weapon, critical_hit, false, false );
546 } else if( has_force_technique ) {
547 technique_id = *force_technique;
548 } else {
549 technique_id = tec_none;
550 }
551
552 // if you have two broken arms you aren't doing any martial arts
553 // and your hits are not going to hurt very much
554 if( get_working_arm_count() < 1 ) {
555 technique_id = tec_none;
556 d.mult_damage( 0.1 );
557 }
558 // polearms and pikes (but not spears) do less damage to adjacent targets
559 if( cur_weapon.reach_range( *this ) > 1 && !reach_attacking &&
560 cur_weapon.has_flag( "POLEARM" ) ) {
561 d.mult_damage( 0.7 );
562 }
563
564 const ma_technique &technique = technique_id.obj();
565
566 // Handles effects as well; not done in melee_affect_*
567 if( technique.id != tec_none ) {
568 perform_technique( technique, t, d, move_cost );
569 }
570
571 // Proceed with melee attack.
572 if( !t.is_dead_state() ) {
573 // Handles speed penalties to monster & us, etc
574 std::string specialmsg = melee_special_effects( t, d, cur_weapon );
575
576 // gets overwritten with the dealt damage values
577 dealt_damage_instance dealt_dam;
578 dealt_damage_instance dealt_special_dam;
579 if( allow_special ) {
580 perform_special_attacks( t, dealt_special_dam );
581 }
582 t.deal_melee_hit( this, hit_spread, critical_hit, d, dealt_dam );
583 if( dealt_special_dam.type_damage( DT_CUT ) > 0 ||
584 dealt_special_dam.type_damage( DT_STAB ) > 0 ||
585 ( cur_weapon.is_null() && ( dealt_dam.type_damage( DT_CUT ) > 0 ||
586 dealt_dam.type_damage( DT_STAB ) > 0 ) ) ) {
587 if( has_trait( trait_POISONOUS ) ) {
588 add_msg_if_player( m_good, _( "You poison %s!" ), t.disp_name() );
589 t.add_effect( effect_poison, 6_turns );
590 } else if( has_trait( trait_POISONOUS2 ) ) {
591 add_msg_if_player( m_good, _( "You inject your venom into %s!" ),
592 t.disp_name() );
593 t.add_effect( effect_badpoison, 6_turns );
594 }
595 }
596
597 // Make a rather quiet sound, to alert any nearby monsters
598 if( !is_quiet() ) { // check martial arts silence
599 //sound generated later
600 sounds::sound( pos(), 8, sounds::sound_t::combat, "whack!" );
601 }
602 std::string material = "flesh";
603 if( t.is_monster() ) {
604 const monster *m = dynamic_cast<const monster *>( &t );
605 if( m->made_of( material_id( "steel" ) ) ) {
606 material = "steel";
607 }
608 }
609 sfx::generate_melee_sound( pos(), t.pos(), true, t.is_monster(), material );
610 int dam = dealt_dam.total_damage();
612
613 // Practice melee and relevant weapon skill (if any) except when using CQB bionic
614 if( !has_active_bionic( bio_cqb ) ) {
615 melee_train( *this, 5, 10, cur_weapon );
616 }
617
618 if( dam >= 5 && has_artifact_with( AEP_SAP_LIFE ) ) {
619 healall( rng( dam / 10, dam / 5 ) );
620 }
621
622 // Treat monster as seen if we see it before or after the attack
623 if( seen || g->u.sees( t ) ) {
624 std::string message = melee_message( technique, *this, dealt_dam );
625 player_hit_message( this, message, t, dam, critical_hit );
626 } else {
627 add_msg_player_or_npc( m_good, _( "You hit something." ),
628 _( "<npcname> hits something." ) );
629 }
630
631 if( !specialmsg.empty() ) {
632 add_msg_if_player( m_neutral, specialmsg );
633 }
634
635 if( critical_hit ) {
636 // trigger martial arts on-crit effects
637 martial_arts_data->ma_oncrit_effects( *this );
638 }
639
640 }
641
643 did_hit( t );
644
645 if( t.is_dead_state() ) {
646 // trigger martial arts on-kill effects
647 martial_arts_data->ma_onkill_effects( *this );
648 }
649 }
650
651 const int melee = get_skill_level( skill_melee );
652
653 // Previously calculated as 2_gram * std::max( 1, str_cur )
654 const int weight_cost = cur_weapon.weight() / ( 16_gram );
655 const int encumbrance_cost = roll_remainder( ( encumb( bp_arm_l ) + encumb( bp_arm_r ) ) *
656 2.0f );
657 const int deft_bonus = hit_spread < 0 && has_trait( trait_DEFT ) ? 50 : 0;
658 const float strbonus = 1 / ( 2 + ( str_cur * 0.25f ) );
659 const float skill_cost = std::max( 0.667f, static_cast<float>( ( 30.0f - melee ) / 30.0f ) );
660 /** @EFFECT_MELEE and @EFFECT_STR reduce stamina cost of melee attacks */
661 const int mod_sta = -( weight_cost + encumbrance_cost - deft_bonus + 50 ) * skill_cost *
662 ( 0.75f + strbonus );
663 mod_stamina( std::min( -50, mod_sta ) );
664 add_msg( m_debug, "Stamina burn: %d", std::min( -50, mod_sta ) );
666 // trigger martial arts on-attack effects
667 martial_arts_data->ma_onattack_effects( *this );
668 // some things (shattering weapons) can harm the attacking creature.
670 if( t.as_character() ) {
672 t.as_character()->on_hit( this, bodypart_id( "num_bp" ), &dp );
673 }
674 return;
675}
int attack_cost(const item &weap) const
Returns cost (in moves) of attacking with given item (no modifiers, like stuck)
Definition: melee.cpp:2279
bool can_miss_recovery(const item &weap) const
Returns true if the player is able to use a miss recovery technique.
std::string melee_special_effects(Creature &t, damage_instance &d, item &weap)
Handles combat effects, returns a string of any valid combat effect messages.
Definition: melee.cpp:1875
void perform_special_attacks(Creature &t, dealt_damage_instance &dealt_dam)
Performs special attacks and their effects (poisonous, stinger, etc.)
Definition: melee.cpp:1848
float hit_roll() const override
Returns the player's basic hit roll that is compared to the target's dodge roll.
Definition: melee.cpp:358
bool scored_crit(float target_dodge, const item &weap) const
Returns true if the player scores a critical hit.
Definition: melee.cpp:783
bool reach_attacking
Definition: character.h:621
void did_hit(Creature &target)
Handles special effects when the Character hits a Creature.
Definition: character.cpp:8298
void on_hit(Creature *source, bodypart_id bp_hit, dealt_projectile_attack const *proj) override
This creature just got hit by an attack - possibly special/ranged attack - from source.
Definition: character.cpp:8303
void perform_technique(const ma_technique &technique, Creature &t, damage_instance &di, int &move_cost)
Definition: melee.cpp:1426
std::string get_miss_reason()
Returns an explanation for why the player would miss a melee attack.
Definition: melee.cpp:390
void roll_all_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds all 3 types of physical damage to instance.
Definition: melee.cpp:412
bool is_quiet() const
Returns true if the player has quiet melee attacks.
virtual bool is_monster() const
Definition: creature.h:101
virtual Character * as_character()
Definition: creature.h:116
virtual int deal_melee_attack(Creature *source, int hitroll)
Definition: creature.cpp:505
virtual float dodge_roll()=0
virtual void deal_melee_hit(Creature *source, int hit_spread, bool critical_hit, const damage_instance &dam, dealt_damage_instance &dealt_dam)
Definition: creature.cpp:524
virtual bool is_dead_state() const =0
int reach_range(const Character &guy) const
Max range of melee attack this weapon can be used for.
Definition: item.cpp:5292
matec_id id
Definition: martialarts.h:97
std::string avatar_message
Definition: martialarts.h:112
bool made_of(const material_id &m) const override
Definition: monster.cpp:983
@ AEP_SAP_LIFE
Definition: enums.h:119
void player_hit_message(Character *attacker, const std::string &message, Creature &t, int dam, bool crit=false)
Definition: melee.cpp:2217
static const efftype_id effect_badpoison("badpoison")
std::string melee_message(const ma_technique &tec, Character &p, const dealt_damage_instance &ddi)
Definition: melee.cpp:2099
static const efftype_id effect_hit_by_player("hit_by_player")
int stumble(Character &u, const item &weap)
Definition: melee.cpp:767
static const trait_id trait_POISONOUS("POISONOUS")
static void melee_train(Character &p, int lo, int hi, const item &weap)
Definition: melee.cpp:420
static const trait_id trait_DEFT("DEFT")
static const efftype_id effect_poison("poison")
static const trait_id trait_POISONOUS2("POISONOUS2")
void smash_specific(monster *z, Creature *target)
Definition: monattack.cpp:1103
void generate_melee_sound(const tripoint &source, const tripoint &target, bool hit, bool targ_mon=false, const std::string &material="flesh")
Definition: sounds.cpp:1606
int actual_crit_count
Definition: melee.h:13

References _, melee_statistic_data::actual_crit_count, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), AEP_SAP_LIFE, Creature::as_character(), item::attack_cost(), attack_cost(), melee_statistic_data::attack_count, ma_technique::avatar_message, bio_cqb, bp_arm_l, bp_arm_r, can_miss_recovery(), Creature::check_dead_state(), sounds::combat, melee_statistic_data::damage_amount, Creature::deal_melee_attack(), Creature::deal_melee_hit(), did_hit(), Creature::disp_name(), Creature::dodge_roll(), DT_CUT, DT_STAB, effect_badpoison, effect_hit_by_player, effect_poison, encumb(), g, sfx::generate_melee_sound(), get_miss_reason(), get_skill_level(), get_working_arm_count(), has_active_bionic(), has_artifact_with(), item::has_flag(), has_trait(), healall(), melee_statistic_data::hit_count, hit_roll(), ma_technique::id, Creature::is_dead_state(), Creature::is_monster(), is_mounted(), item::is_null(), Creature::is_player(), is_quiet(), m_bad, m_debug, m_good, m_info, m_neutral, monster::made_of(), martial_arts_data, melee_message(), melee_special_effects(), melee::melee_stats, melee_train(), mapgen_defer::message, MF_RIDEABLE_MECH, Creature::mod_moves(), mod_stamina(), mounted_creature, move_cost(), damage_instance::mult_damage(), name, string_id< T >::obj(), on_hit(), one_in(), perform_special_attacks(), perform_technique(), pick_technique(), player_hit_message(), Creature::pos(), pos(), primary_weapon(), reach_attacking, item::reach_range(), rng(), roll_all_damage(), roll_remainder(), scored_crit(), skill_melee, mattack::smash_specific(), sounds::sound(), str_cur, stumble(), tec_none, dealt_damage_instance::total_damage(), trait_DEFT, trait_POISONOUS, trait_POISONOUS2, dealt_damage_instance::type_damage(), used_weapon(), and item::weight().

Referenced by block_hit(), npc::execute_action(), monexamine::mfriend_menu(), avatar_action::move(), npc::move_to(), game::npc_menu(), on_dodge(), perform_technique(), monexamine::pet_menu(), and reach_attack().

◆ melee_special_effects()

std::string Character::melee_special_effects ( Creature t,
damage_instance d,
item weap 
)

Handles combat effects, returns a string of any valid combat effect messages.

Strength increases chance of breaking glass weapons (NEGATIVE)

Definition at line 1875 of file melee.cpp.

1876{
1877 std::string dump;
1878
1879 std::string target = t.disp_name();
1880
1881 const bionic_id bio_shock( "bio_shock" );
1883 ( !is_armed() || primary_weapon().conductive() ) ) {
1885 d.add_damage( DT_ELECTRIC, rng( 2, 10 ) );
1886
1887 if( is_player() ) {
1888 dump += string_format( _( "You shock %s." ), target ) + "\n";
1889 } else {
1890 add_msg_if_npc( _( "<npcname> shocks %s." ), target );
1891 }
1892 }
1893
1894 const bionic_id bio_heat_absorb( "bio_heat_absorb" );
1895 if( has_active_bionic( bio_heat_absorb ) && !is_armed() && t.is_warm() ) {
1897 d.add_damage( DT_COLD, 3 );
1898 if( is_player() ) {
1899 dump += string_format( _( "You drain %s's body heat." ), target ) + "\n";
1900 } else {
1901 add_msg_if_npc( _( "<npcname> drains %s's body heat!" ), target );
1902 }
1903 }
1904
1905 if( primary_weapon().has_flag( "FLAMING" ) ) {
1906 d.add_damage( DT_HEAT, rng( 1, 8 ) );
1907
1908 if( is_player() ) {
1909 dump += string_format( _( "You burn %s." ), target ) + "\n";
1910 } else {
1911 add_msg_player_or_npc( _( "<npcname> burns %s." ), target );
1912 }
1913 }
1914
1915 //Hurting the wielder from poorly-chosen weapons
1916 if( weap.has_flag( "HURT_WHEN_WIELDED" ) && x_in_y( 2, 3 ) ) {
1917 add_msg_if_player( m_bad, _( "The %s cuts your hand!" ), weap.tname() );
1918 deal_damage( nullptr, bodypart_id( "hand_r" ), damage_instance::physical( 0,
1919 weap.damage_melee( DT_CUT ), 0 ) );
1920 if( weap.is_two_handed( *this ) ) { // Hurt left hand too, if it was big
1921 deal_damage( nullptr, bodypart_id( "hand_l" ), damage_instance::physical( 0,
1922 weap.damage_melee( DT_CUT ), 0 ) );
1923 }
1924 }
1925
1926 const int vol = weap.volume() / 250_ml;
1927 // Glass weapons shatter sometimes
1928 if( weap.made_of( material_id( "glass" ) ) &&
1929 /** @EFFECT_STR increases chance of breaking glass weapons (NEGATIVE) */
1930 rng( 0, vol + 8 ) < vol + str_cur ) {
1931 if( is_player() ) {
1932 dump += string_format( _( "Your %s shatters!" ), weap.tname() ) + "\n";
1933 } else {
1934 add_msg_player_or_npc( m_bad, _( "Your %s shatters!" ),
1935 _( "<npcname>'s %s shatters!" ),
1936 weap.tname() );
1937 }
1938
1939 sounds::sound( pos(), 16, sounds::sound_t::combat, "Crack!", true, "smash_success",
1940 "smash_glass_contents" );
1941 // Dump its contents on the ground
1942 weap.contents.spill_contents( pos() );
1943 // Take damage
1944 deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1945 0 ) );
1946 if( weap.is_two_handed( *this ) ) { // Hurt left arm too, if it was big
1947 //redeclare shatter_dam because deal_damage mutates it
1948 deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance::physical( 0, rng( 0, vol * 2 ),
1949 0 ) );
1950 }
1951 d.add_damage( DT_CUT, rng( 0, 5 + static_cast<int>( vol * 1.5 ) ) ); // Hurt the monster extra
1952 remove_weapon();
1953 }
1954
1955 if( !t.is_hallucination() ) {
1956 handle_melee_wear( weap );
1957 }
1958
1959 // on-hit effects for martial arts
1960 martial_arts_data->ma_onhit_effects( *this );
1961
1962 return dump;
1963}
item remove_weapon()
Definition: character.cpp:2517
virtual bool is_warm() const
Definition: creature.cpp:988
int damage_melee(damage_type dt) const
Damage of given type caused when this item is used as melee weapon.
Definition: item.cpp:5215
static const bionic_id bio_shock("bio_shock")
static const bionic_id bio_heat_absorb("bio_heat_absorb")

References _, damage_instance::add_damage(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_heat_absorb, bio_shock, sounds::combat, item::contents, item::damage_melee(), deal_damage(), Creature::disp_name(), DT_COLD, DT_CUT, DT_ELECTRIC, DT_HEAT, get_power_level(), handle_melee_wear(), has_active_bionic(), Creature::has_flag(), item::has_flag(), is_armed(), Creature::is_hallucination(), Creature::is_player(), item::is_two_handed(), Creature::is_warm(), m_bad, item::made_of(), martial_arts_data, mod_power_level(), damage_instance::physical(), pos(), bionic_data::power_trigger, primary_weapon(), remove_weapon(), rng(), sounds::sound(), item_contents::spill_contents(), str_cur, string_format(), item::tname(), item::volume(), and x_in_y().

Referenced by melee_attack().

◆ metabolic_rate()

float Character::metabolic_rate ( ) const

Current metabolic rate due to traits, hunger, speed, etc.

Definition at line 614 of file consumption.cpp.

615{
616 return metabolic_rate_base();
617}

References metabolic_rate_base().

Referenced by calc_needs_rates().

◆ metabolic_rate_base()

float Character::metabolic_rate_base ( ) const

Stable base metabolic rate due to traits.

Definition at line 601 of file consumption.cpp.

602{
603 static const std::string hunger_rate_string( "PLAYER_HUNGER_RATE" );
604 static const std::string metabolism_modifier( "metabolism_modifier" );
605
606 float hunger_rate = get_option< float >( hunger_rate_string );
607 float mut_bonus = 1.0f + mutation_value( metabolism_modifier );
608 float with_mut = hunger_rate * mut_bonus;
609 float ench_bonus = bonus_from_enchantments( with_mut, enchant_vals::mod::METABOLISM );
610
611 return std::max( 0.0f, with_mut + ench_bonus );
612}

References bonus_from_enchantments(), enchant_vals::METABOLISM, and mutation_value().

Referenced by bmr(), and metabolic_rate().

◆ mod_base_age()

void Character::mod_base_age ( int  mod)

Definition at line 6795 of file character.cpp.

6796{
6797 init_age += mod;
6798}

References init_age.

Referenced by set_description().

◆ mod_base_height()

void Character::mod_base_height ( int  mod)

Definition at line 6824 of file character.cpp.

6825{
6826 init_height += mod;
6827}

References init_height.

Referenced by set_description().

◆ mod_dex_bonus()

void Character::mod_dex_bonus ( int  ndex)
virtual

◆ mod_fatigue()

◆ mod_healthy()

void Character::mod_healthy ( int  nhealthy)
virtual

Modifiers for health values exclusive to characters.

Definition at line 4271 of file character.cpp.

4272{
4273 float mut_rate = 1.0f;
4274 for( const trait_id &mut : get_mutations() ) {
4275 mut_rate *= mut.obj().healthy_rate;
4276 }
4277 healthy += nhealthy * mut_rate;
4278}

References get_mutations(), and healthy.

Referenced by iuse::adrenaline_injector(), mod_stat(), process_one_effect(), spell_effect::recover_energy(), and update_health().

◆ mod_healthy_mod()

void Character::mod_healthy_mod ( int  nhealthy_mod,
int  cap 
)
virtual

Definition at line 4283 of file character.cpp.

4284{
4285 // TODO: This really should be a full morale-like system, with per-effect caps
4286 // and durations. This version prevents any single effect from exceeding its
4287 // intended ceiling, but multiple effects will overlap instead of adding.
4288
4289 // Cap indicates how far the mod is allowed to shift in this direction.
4290 // It can have a different sign to the mod, e.g. for items that treat
4291 // extremely low health, but can't make you healthy.
4292 if( nhealthy_mod == 0 || cap == 0 ) {
4293 return;
4294 }
4295 int low_cap;
4296 int high_cap;
4297 if( nhealthy_mod < 0 ) {
4298 low_cap = cap;
4299 high_cap = 200;
4300 } else {
4301 low_cap = -200;
4302 high_cap = cap;
4303 }
4304
4305 // If we're already out-of-bounds, we don't need to do anything.
4306 if( ( healthy_mod <= low_cap && nhealthy_mod < 0 ) ||
4307 ( healthy_mod >= high_cap && nhealthy_mod > 0 ) ) {
4308 return;
4309 }
4310
4311 healthy_mod += nhealthy_mod;
4312
4313 // Since we already bailed out if we were out-of-bounds, we can
4314 // just clamp to the boundaries here.
4315 healthy_mod = std::min( healthy_mod, high_cap );
4316 healthy_mod = std::max( healthy_mod, low_cap );
4317}

References healthy_mod.

Referenced by addict_effect(), iuse::blech(), check_needs_extremes(), consume_effects(), hardcoded_effects(), modify_health(), iuse::mycus(), iuse::plantblech(), process_one_effect(), rooted(), suffer_feral_kill_withdrawl(), suffer_from_bad_bionics(), suffer_from_other_mutations(), update_health(), and iuse::vaccine().

◆ mod_int_bonus()

void Character::mod_int_bonus ( int  nint)
virtual

◆ mod_max_power_level()

void Character::mod_max_power_level ( const units::energy npower_max)

Definition at line 1937 of file character.cpp.

1938{
1939 max_power_level += npower_max;
1940}

References max_power_level.

Referenced by add_bionic(), perform_uninstall(), and uninstall_bionic().

◆ mod_pain()

void Character::mod_pain ( int  npain)
overridevirtual

Modifies a pain value by player traits before passing it to Creature::mod_pain()

Reimplemented from Creature.

Definition at line 764 of file character.cpp.

765{
766 if( npain > 0 ) {
768 return;
769 }
770 // always increase pain gained by one from these bad mutations
771 if( has_trait( trait_MOREPAIN ) ) {
772 npain += std::max( 1, roll_remainder( npain * 0.25 ) );
773 } else if( has_trait( trait_MOREPAIN2 ) ) {
774 npain += std::max( 1, roll_remainder( npain * 0.5 ) );
775 } else if( has_trait( trait_MOREPAIN3 ) ) {
776 npain += std::max( 1, roll_remainder( npain * 1.0 ) );
777 }
778
779 if( npain > 1 ) {
780 // if it's 1 it'll just become 0, which is bad
782 npain = roll_remainder( npain * 0.5 );
783 } else if( has_trait( trait_PAINRESIST ) ) {
784 npain = roll_remainder( npain * 0.67 );
785 }
786 }
787 }
788 Creature::mod_pain( npain );
789}
static const efftype_id effect_narcosis("narcosis")
static const trait_id trait_MOREPAIN("MORE_PAIN")
static const trait_id trait_PAINRESIST_TROGLO("PAINRESIST_TROGLO")
static const trait_id trait_MOREPAIN2("MORE_PAIN2")
static const trait_id trait_PAINRESIST("PAINRESIST")
static const trait_id trait_MOREPAIN3("MORE_PAIN3")
virtual void mod_pain(int npain)
Definition: creature.cpp:1388

References effect_narcosis, Creature::has_effect(), has_trait(), Creature::mod_pain(), roll_remainder(), trait_MOREPAIN, trait_MOREPAIN2, trait_MOREPAIN3, trait_NOPAIN, trait_PAINRESIST, and trait_PAINRESIST_TROGLO.

Referenced by addict_effect(), iuse::antiparasitic(), apply_damage(), iexamine::autodoc(), iuse::blech(), iuse::blood_draw(), blood_magic(), burn_move_stamina(), activity_handlers::burrow_finish(), cauterize_actor::cauterize_effect(), debug_menu::character_edit_menu(), consume_effects(), eff_fun_bleed(), iuse::ehandcuffs(), game::find_or_make_stairs(), game::grabbed_furn_move(), game::grabbed_veh_move(), hardcoded_effects(), hurtall(), marloss_common(), game::mon_info_update(), iuse::mycus(), activity_handlers::pickaxe_finish(), map::player_in_field(), process_bionic(), process_one_effect(), sounds::process_sound_markers(), iuse::purify_iv(), iuse::purify_smart(), spell_effect::recover_energy(), regen(), suffer_feral_kill_withdrawl(), suffer_from_bad_bionics(), suffer_from_chemimbalance(), suffer_from_sunburn(), suffer_without_sleep(), try_reject_mutagen(), update_needs(), mutagen_actor::use(), mutagen_iv_actor::use(), and iuse::vaccine().

◆ mod_painkiller()

void Character::mod_painkiller ( int  npkill)

◆ mod_per_bonus()

void Character::mod_per_bonus ( int  nper)
virtual

◆ mod_power_level()

void Character::mod_power_level ( const units::energy npower)

Definition at line 1925 of file character.cpp.

1926{
1927 // Remaining capacity between current and maximum power levels we can make use of.
1928 const units::energy remaining_capacity = get_max_power_level() - get_power_level();
1929 // We can't add more than remaining capacity, so get the minimum of the two
1930 const units::energy minned_npower = std::min( npower, remaining_capacity );
1931 // new candidate power level
1932 const units::energy new_power = get_power_level() + minned_npower;
1933 // set new power level while prevending it from going negative
1934 set_power_level( std::max( 0_kJ, new_power ) );
1935}

References get_max_power_level(), get_power_level(), and set_power_level().

Referenced by activate_bionic(), item::ammo_consume(), burn_fuel(), deactivate_bionic(), npc::discharge_cbm_weapon(), do_skill_rust(), iuse::ehandcuffs(), explosion_handler::emp_blast(), feed_furnace_with(), aim_activity_actor::finish(), iexamine::fireplace(), hack_attempt(), melee_special_effects(), modify_morale(), game::monmove(), on_hit(), game::on_move_effects(), passive_power_gen(), game::phasing_move(), process_bionic(), npc::recharge_cbm(), spell_effect::recover_energy(), mattack::riotbot(), activity_handlers::spellcasting_finish(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_radiation(), suffer_while_underwater(), try_start_hacking(), character_funcs::try_uncanny_dodge(), update_stamina(), use_charges(), and use_fire().

◆ mod_rad()

void Character::mod_rad ( int  mod)

Definition at line 7085 of file character.cpp.

7086{
7087 if( has_trait_flag( "NO_RADIATION" ) ) {
7088 return;
7089 }
7090 set_rad( std::max( 0, get_rad() + mod ) );
7091}

References get_rad(), has_trait_flag(), and set_rad().

Referenced by irradiate(), game::process_artifact(), process_bionic(), process_one_effect(), regen(), and suffer_from_radiation().

◆ mod_skill_level()

void Character::mod_skill_level ( const skill_id ident,
int  delta 
)

Definition at line 3365 of file character.cpp.

3366{
3367 _skills->mod_skill_level( ident, delta );
3368}

References _skills.

Referenced by avatar::create(), npc::randomize(), and set_skills().

◆ mod_sleep_deprivation()

void Character::mod_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4460 of file character.cpp.

4461{
4462 set_sleep_deprivation( sleep_deprivation + nsleep_deprivation );
4463}

References set_sleep_deprivation(), and sleep_deprivation.

Referenced by update_needs().

◆ mod_stamina()

◆ mod_stat()

void Character::mod_stat ( const std::string &  stat,
float  modifier 
)
overridevirtual

Reimplemented from Creature.

Definition at line 546 of file character.cpp.

547{
548 if( stat == "str" ) {
549 mod_str_bonus( modifier );
550 } else if( stat == "dex" ) {
551 mod_dex_bonus( modifier );
552 } else if( stat == "per" ) {
553 mod_per_bonus( modifier );
554 } else if( stat == "int" ) {
555 mod_int_bonus( modifier );
556 } else if( stat == "healthy" ) {
557 mod_healthy( modifier );
558 } else if( stat == "kcal" ) {
559 mod_stored_kcal( modifier );
560 } else if( stat == "hunger" ) {
561 mod_stored_kcal( -10 * modifier );
562 } else if( stat == "thirst" ) {
563 mod_thirst( modifier );
564 } else if( stat == "fatigue" ) {
565 mod_fatigue( modifier );
566 } else if( stat == "oxygen" ) {
567 oxygen += modifier;
568 } else if( stat == "stamina" ) {
569 mod_stamina( modifier );
570 } else {
571 Creature::mod_stat( stat, modifier );
572 }
573}
virtual void mod_healthy(int nhealthy)
Modifiers for health values exclusive to characters.
Definition: character.cpp:4271
virtual void mod_stat(const std::string &stat, float modifier)
Definition: creature.cpp:1747

References mod_dex_bonus(), mod_fatigue(), mod_healthy(), mod_int_bonus(), mod_per_bonus(), mod_stamina(), Creature::mod_stat(), mod_stored_kcal(), mod_str_bonus(), mod_thirst(), and oxygen.

Referenced by apply_skill_boost(), shout(), and consume_drug_iuse::use().

◆ mod_stim()

◆ mod_stored_kcal()

◆ mod_stored_nutr()

void Character::mod_stored_nutr ( int  nnutr)
virtual

Definition at line 4329 of file character.cpp.

4330{
4331 // nutr is legacy type code, this function simply converts old nutrition to new kcal
4332 mod_stored_kcal( -1 * std::round( nnutr * 2500.0f / ( 12 * 24 ) ) );
4333}

References mod_stored_kcal().

Referenced by iuse::blood_draw(), activity_handlers::burrow_finish(), game::find_or_make_stairs(), activity_handlers::hacksaw_finish(), hardcoded_effects(), activity_handlers::jackhammer_finish(), marloss_common(), iuse::mycus(), activity_handlers::pickaxe_finish(), iuse::purify_iv(), suffer_mutation_power(), and mutagen_actor::use().

◆ mod_str_bonus()

void Character::mod_str_bonus ( int  nstr)
virtual

◆ mod_thirst()

◆ modify_addiction()

void Character::modify_addiction ( const islot_comestible comest)

Used to apply addiction modifications from food and medication.

Definition at line 1064 of file consumption.cpp.

1065{
1066 add_addiction( comest.add, comest.addict );
1067 if( addiction_craving( comest.add ) != MORALE_NULL ) {
1068 rem_morale( addiction_craving( comest.add ) );
1069 }
1070}
morale_type addiction_craving(add_type const cur)
Definition: addiction.cpp:307
void add_addiction(add_type type, int strength)
Adds an addiction to the player.
Definition: suffer.cpp:1844
add_type add
effects of addiction
Definition: itype.h:143
int addict
addiction potential
Definition: itype.h:140

References islot_comestible::add, add_addiction(), islot_comestible::addict, addiction_craving(), MORALE_NULL, and rem_morale().

Referenced by consume_effects(), and consume_med().

◆ modify_fatigue()

void Character::modify_fatigue ( const islot_comestible comest)

Used to apply fatigue modifications from food and medication.

Definition at line 1054 of file consumption.cpp.

1055{
1056 mod_fatigue( -comest.fatigue_mod );
1057}
int fatigue_mod
fatigue altering effect
Definition: itype.h:149

References islot_comestible::fatigue_mod, and mod_fatigue().

Referenced by consume_effects(), and consume_med().

◆ modify_health()

void Character::modify_health ( const islot_comestible comest)

Used to apply health modifications from food and medication.

Definition at line 1011 of file consumption.cpp.

1012{
1013 const int effective_health = comest.healthy;
1014 // Effectively no cap on health modifiers from food and meds
1015 const int health_cap = 200;
1016 mod_healthy_mod( effective_health, effective_health >= 0 ? health_cap : -health_cap );
1017}
int healthy
TODO: add documentation.
Definition: itype.h:158

References islot_comestible::healthy, and mod_healthy_mod().

Referenced by consume_effects(), and consume_med().

◆ modify_morale()

void Character::modify_morale ( item food,
int  nutr = 0 
)

Used to apply morale modifications from food and medication.

Definition at line 1072 of file consumption.cpp.

1073{
1074 time_duration morale_time = 2_hours;
1075 if( food.has_flag( flag_EATEN_HOT ) ) {
1076 auto heater = find_food_heater( *this, crafting_inventory(),
1077 get_map().has_nearby_fire( pos(), PICKUP_RANGE ) );
1078 if( heater && heater->consume( *this ) ) {
1080 _( "You heat up your %1$s using the %2$s." ),
1081 _( "<npcname> heats up their %1$s using the %2$s." ),
1082 food.tname(), heater->it.tname() );
1083 food.unset_flag( flag_COLD );
1084 food.unset_flag( flag_VERY_COLD );
1085 morale_time = 3_hours;
1086 int clamped_nutr = std::max( 5, std::min( 20, nutr / 10 ) );
1087 add_morale( MORALE_FOOD_HOT, clamped_nutr, 20, morale_time, morale_time / 2 );
1088 }
1089 }
1090
1091 std::pair<int, int> fun = fun_for( food );
1092 if( fun.first < 0 ) {
1094 get_power_level() > units::from_kilojoule( -fun.first ) ) {
1095 mod_power_level( units::from_kilojoule( std::min( 0, fun_for( food ).first ) ) );
1096 } else {
1097 add_morale( MORALE_FOOD_BAD, fun.first, fun.second, morale_time, morale_time / 2, false,
1098 food.type );
1099 }
1100 } else if( fun.first > 0 ) {
1101 add_morale( MORALE_FOOD_GOOD, fun.first, fun.second, morale_time, morale_time / 2, false,
1102 food.type );
1103 }
1104
1105 if( food.has_flag( flag_HIDDEN_HALLU ) ) {
1106 if( has_trait( trait_SPIRITUAL ) ) {
1107 add_morale( MORALE_FOOD_GOOD, 36, 72, 2_hours, 1_hours, false );
1108 } else {
1109 add_morale( MORALE_FOOD_GOOD, 18, 36, 1_hours, 30_minutes, false );
1110 }
1111 }
1112
1113 if( food.has_flag( flag_CANNIBALISM ) ) {
1114 const bool cannibal = has_trait( trait_CANNIBAL );
1115 const bool psycho = has_trait( trait_PSYCHOPATH );
1116 const bool sapiovore = has_trait( trait_SAPIOVORE );
1117 if( cannibal ) {
1118 add_msg_if_player( m_good, _( "You indulge your shameful hunger." ) );
1119 add_morale( MORALE_CANNIBAL, 20, 200 );
1120 } else if( psycho || sapiovore ) {
1121 // Nothing - doesn't care enough to print a message
1122 } else {
1123 add_msg_if_player( m_bad, _( "You feel horrible for eating a person." ) );
1124 add_morale( MORALE_CANNIBAL, -60, -400, 60_minutes, 30_minutes );
1125 }
1126 }
1127
1128 // Allergy check for food that is ingested (not gum)
1129 if( !food.has_flag( "NO_INGEST" ) ) {
1130 const auto allergy = allergy_type( food );
1131 if( allergy != MORALE_NULL ) {
1132 add_msg_if_player( m_bad, _( "Yuck! How can anybody eat this stuff?" ) );
1133 add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
1134 }
1135 if( food.has_flag( flag_ALLERGEN_JUNK ) ) {
1136 if( has_trait( trait_PROJUNK ) ) {
1137 add_msg_if_player( m_good, _( "Mmm, junk food." ) );
1138 add_morale( MORALE_SWEETTOOTH, 5, 30, 30_minutes, 24_minutes );
1139 }
1140 if( has_trait( trait_PROJUNK2 ) ) {
1141 if( !one_in( 100 ) ) {
1142 add_msg_if_player( m_good, _( "When life's got you down, there's always sugar." ) );
1143 } else {
1144 add_msg_if_player( m_good, _( "They may do what they must… you've already won." ) );
1145 }
1146 add_morale( MORALE_SWEETTOOTH, 10, 50, 1_hours, 50_minutes );
1147 }
1148 // Carnivores CAN eat junk food, but they won't like it much.
1149 // Pizza-scraping happens in consume_effects.
1151 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1152 add_morale( MORALE_NO_DIGEST, -25, -125, 30_minutes, 24_minutes );
1153 }
1154 }
1155 }
1156 const bool chew = food.get_comestible()->comesttype == comesttype_FOOD ||
1158 if( !food.rotten() && chew && has_trait( trait_SAPROPHAGE ) ) {
1159 // It's OK to *drink* things that haven't rotted. Alternative is to ban water. D:
1160 add_msg_if_player( m_bad, _( "Your stomach begins gurgling and you feel bloated and ill." ) );
1161 add_morale( MORALE_NO_DIGEST, -75, -400, 30_minutes, 24_minutes );
1162 }
1163 if( food.has_flag( flag_URSINE_HONEY ) && ( !crossed_threshold() ||
1165 mutation_category_level["URSINE"] > 40 ) {
1166 // Need at least 5 bear mutations for effect to show, to filter out mutations in common with other categories
1167 int honey_fun = has_trait( trait_THRESH_URSINE ) ?
1168 std::min( mutation_category_level["URSINE"] / 8, 20 ) :
1169 mutation_category_level["URSINE"] / 12;
1170 if( honey_fun < 10 ) {
1171 add_msg_if_player( m_good, _( "You find the sweet taste of honey surprisingly palatable." ) );
1172 } else {
1173 add_msg_if_player( m_good, _( "You feast upon the sweet honey." ) );
1174 }
1175 add_morale( MORALE_HONEY, honey_fun, 100 );
1176 }
1177}
morale_type allergy_type(const item &food) const
Returns allergy type or MORALE_NULL if not allergic for this character.
std::pair< int, int > fun_for(const item &comest) const
Handles the enjoyability value for a comestible.
item & unset_flag(const std::string &flag)
Idempotent filter removing an item specific flag.
Definition: item.cpp:5365
static const bionic_id bio_taste_blocker("bio_taste_blocker")
static const trait_id trait_THRESH_URSINE("THRESH_URSINE")
static const std::string flag_URSINE_HONEY("URSINE_HONEY")
static std::optional< prepared_item_consumption > find_food_heater(Character &c, const inventory &inv, bool has_fire)
static const std::string flag_CANNIBALISM("CANNIBALISM")
static const trait_id trait_SAPIOVORE("SAPIOVORE")
static const trait_id trait_PSYCHOPATH("PSYCHOPATH")
static const trait_id trait_PROJUNK("PROJUNK")
static const trait_id trait_SPIRITUAL("SPIRITUAL")
static const std::string flag_EATEN_HOT("EATEN_HOT")
static const trait_id trait_CANNIBAL("CANNIBAL")
const morale_type MORALE_HONEY("morale_honey")
const morale_type MORALE_SWEETTOOTH("morale_sweettooth")
const morale_type MORALE_NO_DIGEST("morale_no_digest")
const morale_type MORALE_FOOD_HOT("morale_food_hot")
const morale_type MORALE_FOOD_GOOD("morale_food_good")
const morale_type MORALE_CANNIBAL("morale_cannibal")
const morale_type MORALE_FOOD_BAD("morale_food_bad")

References _, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), allergy, allergy_type(), bio_taste_blocker, iuse::chew(), comesttype_FOOD(), crafting_inventory(), crossed_threshold(), find_food_heater(), flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_COLD(), flag_EATEN_HOT(), flag_HIDDEN_HALLU(), flag_URSINE_HONEY(), flag_USE_EAT_VERB(), flag_VERY_COLD(), units::from_kilojoule(), fun_for(), item::get_comestible(), get_map(), get_power_level(), has_active_bionic(), item::has_flag(), has_trait(), m_bad, m_good, mod_power_level(), MORALE_CANNIBAL, MORALE_FOOD_BAD, MORALE_FOOD_GOOD, MORALE_FOOD_HOT, MORALE_HONEY, MORALE_NO_DIGEST, MORALE_NULL, MORALE_SWEETTOOTH, mutation_category_level, one_in(), PICKUP_RANGE, pos(), item::rotten(), item::tname(), trait_CANNIBAL, trait_CARNIVORE, trait_PROJUNK, trait_PROJUNK2, trait_PSYCHOPATH, trait_SAPIOVORE, trait_SAPROPHAGE, trait_SPIRITUAL, trait_THRESH_URSINE, item::type, and item::unset_flag().

Referenced by consume_effects(), and consume_med().

◆ modify_radiation()

void Character::modify_radiation ( const islot_comestible comest)

Used to apply radiation from food and medication.

Definition at line 1059 of file consumption.cpp.

1060{
1061 irradiate( comest.radiation );
1062}
int radiation
Amount of radiation you get from this comestible.
Definition: itype.h:164

References irradiate(), and islot_comestible::radiation.

Referenced by consume_effects(), and consume_med().

◆ modify_stimulation()

void Character::modify_stimulation ( const islot_comestible comest)

Used to apply stimulation modifications from food and medication.

Definition at line 1019 of file consumption.cpp.

1020{
1021 const int current_stim = get_stim();
1022 if( comest.stim != 0 &&
1023 ( std::abs( current_stim ) < ( std::abs( comest.stim ) * 3 ) ||
1024 sgn( current_stim ) != sgn( comest.stim ) ) ) {
1025 if( comest.stim < 0 ) {
1026 set_stim( std::max( comest.stim * 3, current_stim + comest.stim ) );
1027 } else {
1028 set_stim( std::min( comest.stim * 3, current_stim + comest.stim ) );
1029 }
1030 }
1031 if( has_trait( trait_STIMBOOST ) && ( current_stim > 30 ) &&
1032 ( ( comest.add == add_type::CAFFEINE ) || ( comest.add == add_type::SPEED ) ||
1033 ( comest.add == add_type::COKE ) || ( comest.add == add_type::CRACK ) ) ) {
1034 int hallu_duration = ( current_stim - comest.stim < 30 ) ? current_stim - 30 : comest.stim;
1035 add_effect( effect_visuals, hallu_duration * 30_minutes );
1036 std::vector<std::string> stimboost_msg{ _( "The shadows are getting ever closer." ),
1037 _( "You have a bad feeling about this." ),
1038 _( "A powerful sense of dread comes over you." ),
1039 _( "Your skin starts crawling." ),
1040 _( "They're coming to get you." ),
1041 _( "This might've been a bad idea…" ),
1042 _( "You've really done it this time, haven't you?" ),
1043 _( "You have to stay vigilant. They're always watching…" ),
1044 _( "mistake mistake mistake mistake mistake" ),
1045 _( "Just gotta stay calm, and you'll make it through this." ),
1046 _( "You're starting to feel very jumpy." ),
1047 _( "Something is twitching at the edge of your vision." ),
1048 _( "They know what you've done…" ),
1049 _( "You're feeling even more paranoid than usual." ) };
1050 add_msg_if_player( m_bad, random_entry_ref( stimboost_msg ) );
1051 }
1052}
static const efftype_id effect_visuals("visuals")
static const trait_id trait_STIMBOOST("STIMBOOST")
constexpr int sgn(const T x)
Definition: enums.h:8
std::enable_if<!is_std_array< C >::value, constV & >::type random_entry_ref(const C &container)
Same as above, but with a statically allocated default value (using the default constructor).
Definition: rng.h:149
int stim
stimulant effect
Definition: itype.h:146

References _, islot_comestible::add, Creature::add_effect(), Creature::add_msg_if_player(), CAFFEINE, COKE, CRACK, effect_visuals, get_stim(), has_trait(), m_bad, random_entry_ref(), set_stim(), sgn(), SPEED, islot_comestible::stim, and trait_STIMBOOST.

Referenced by consume_effects(), and consume_med().

◆ mount_creature()

void Character::mount_creature ( monster z)

Definition at line 968 of file character.cpp.

969{
970 tripoint pnt = z.pos();
971 shared_ptr_fast<monster> mons = g->shared_from( z );
972 if( mons == nullptr ) {
973 add_msg( m_debug, "mount_creature(): monster not found in critter_tracker" );
974 return;
975 }
976 add_effect( effect_riding, 1_turns, num_bp );
977 z.add_effect( effect_ridden, 1_turns, num_bp );
978 if( z.has_effect( effect_tied ) ) {
980 if( z.tied_item ) {
981 i_add( *z.tied_item );
982 z.tied_item.reset();
983 }
984 }
986 if( z.has_effect( effect_harnessed ) ) {
988 add_msg_if_player( m_info, _( "You remove the %s's harness." ), z.get_name() );
989 }
990 mounted_creature = mons;
991 mons->mounted_player = this;
992 if( is_avatar() ) {
993 if( g->u.is_hauling() ) {
994 g->u.stop_hauling();
995 }
996 if( g->u.get_grab_type() != OBJECT_NONE ) {
997 add_msg( m_warning, _( "You let go of the grabbed object." ) );
998 g->u.grab( OBJECT_NONE );
999 }
1000 g->place_player( pnt );
1001 } else {
1002 npc &guy = dynamic_cast<npc &>( *this );
1003 guy.setpos( pnt );
1004 }
1005 z.facing = facing;
1006 // Make sure something didn't interrupt this process and knock the player off partway through!
1007 if( has_effect( effect_riding ) ) {
1008 add_msg_if_player( m_good, _( "You climb on the %s." ), z.get_name() );
1009 if( z.has_flag( MF_RIDEABLE_MECH ) ) {
1010 if( !z.type->mech_weapon.is_empty() ) {
1011 auto mechwep = item{ z.type->mech_weapon };
1012 wield( mechwep );
1013 }
1014 add_msg_if_player( m_good, _( "You hear your %s whir to life." ), z.get_name() );
1015 }
1016 add_msg_if_player( m_good, _( "You hear your %s whir to life." ), z.get_name() );
1017 }
1018 // some rideable mechs have night-vision
1020 mod_moves( -100 );
1021}
static const efftype_id effect_tied("tied")
static const efftype_id effect_harnessed("harnessed")
FacingDirection facing
return the direction the creature is facing, for sdl horizontal flip
Definition: creature.h:135
cata::value_ptr< item > tied_item
Definition: monster.h:461
std::string get_name() const override
Definition: monster.cpp:484
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:693
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References _, Creature::add_effect(), monster::add_effect(), add_msg(), Creature::add_msg_if_player(), effect_harnessed, effect_ridden, effect_riding, effect_tied, Creature::facing, g, monster::get_name(), getID(), Creature::has_effect(), monster::has_flag(), i_add(), Creature::is_avatar(), string_id< T >::is_empty(), m_debug, m_good, m_info, m_warning, mtype::mech_weapon, MF_RIDEABLE_MECH, Creature::mod_moves(), mounted_creature, monster::mounted_player_id, num_bp, OBJECT_NONE, monster::pos(), recalc_sight_limits(), Creature::remove_effect(), npc::setpos(), monster::tied_item, monster::type, and wield().

Referenced by activity_handlers::find_mount_do_turn(), and monexamine::mount_pet().

◆ move_effects()

bool Character::move_effects ( bool  attacking)
overridevirtual

Processes effects which may prevent the Character from moving (bear traps, crushed, etc.).

Returns false if movement is stopped.

Strength increases chance to escape pit Dexterity increases chance to escape pit, slightly

Implements Creature.

Definition at line 1476 of file character.cpp.

1477{
1478 if( has_effect( effect_downed ) ) {
1479 try_remove_downed( *this );
1480 return false;
1481 }
1482 if( has_effect( effect_webbed ) ) {
1483 try_remove_webs( *this );
1484 return false;
1485 }
1486 if( has_effect( effect_lightsnare ) ) {
1487 try_remove_lightsnare( *this );
1488 return false;
1489
1490 }
1491 if( has_effect( effect_heavysnare ) ) {
1492 try_remove_heavysnare( *this );
1493 return false;
1494 }
1495 if( has_effect( effect_beartrap ) ) {
1496 try_remove_bear_trap( *this );
1497 return false;
1498 }
1499 if( has_effect( effect_crushed ) ) {
1500 try_remove_crushed( *this );
1501 return false;
1502 }
1503 // Below this point are things that allow for movement if they succeed
1504
1505 // Currently we only have one thing that forces movement if you succeed, should we get more
1506 // than this will need to be reworked to only have success effects if /all/ checks succeed
1507 if( has_effect( effect_in_pit ) ) {
1508 /** @EFFECT_STR increases chance to escape pit */
1509
1510 /** @EFFECT_DEX increases chance to escape pit, slightly */
1511 if( rng( 0, 40 ) > get_str() + get_dex() / 2 ) {
1512 add_msg_if_player( m_bad, _( "You try to escape the pit, but slip back in." ) );
1513 return false;
1514 } else {
1515 add_msg_player_or_npc( m_good, _( "You escape the pit!" ),
1516 _( "<npcname> escapes the pit!" ) );
1518 }
1519 }
1520 if( has_effect( effect_grabbed ) && !attacking && !try_remove_grab( *this ) ) {
1521 // NOLINTNEXTLINE(readability-simplify-boolean-expr)
1522 return false;
1523 }
1524 return true;
1525}
static void try_remove_lightsnare(Character &c)
Definition: character.cpp:1326
static void try_remove_crushed(Character &c)
Definition: character.cpp:1386
static const efftype_id effect_crushed("crushed")
static void try_remove_heavysnare(Character &c)
Definition: character.cpp:1355
static void try_remove_bear_trap(Character &c)
Definition: character.cpp:1290
static void try_remove_webs(Character &c)
Definition: character.cpp:1456
static bool try_remove_grab(Character &c)
Definition: character.cpp:1400
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_in_pit("in_pit")
static void try_remove_downed(Character &c)
Definition: character.cpp:1275

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), effect_beartrap, effect_crushed, effect_downed, effect_grabbed, effect_heavysnare, effect_in_pit, effect_lightsnare, effect_webbed, get_dex(), get_str(), Creature::has_effect(), m_bad, m_good, Creature::remove_effect(), rng(), try_remove_bear_trap(), try_remove_crushed(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by avatar_action::move(), npc::move_to(), and game::vertical_move().

◆ movement_mode_is()

bool Character::movement_mode_is ( character_movemode  mode) const

Check against the character's current movement mode.

Definition at line 1560 of file character.cpp.

1561{
1562 return move_mode == mode;
1563}

References move_mode.

Referenced by map::build_vision_transparency_cache(), avatar::cycle_move_mode(), draw_health_classic(), avatar_action::move(), move_mode_color(), move_mode_string(), game::on_move_effects(), Creature::sees(), game::vertical_move(), and game::walk_move().

◆ mut_cbm_encumb()

void Character::mut_cbm_encumb ( char_encumbrance_data vals) const
protected

Applies encumbrance from mutations and bionics only.

Definition at line 4046 of file character.cpp.

4047{
4048
4049 for( const bionic_id &bid : get_bionics() ) {
4050 for( const std::pair<const bodypart_str_id, int> &element : bid->encumbrance ) {
4051 vals.elems[element.first->token].encumbrance += element.second;
4052 }
4053 }
4054
4056 for( auto &val : vals.elems ) {
4057 val.encumbrance += 3; // Slight encumbrance to all parts except eyes
4058 }
4059 vals.elems[bp_eyes].encumbrance -= 3;
4060 }
4061
4062 // Lower penalty for bps covered only by XL armor
4063 const auto oversize = exclusive_flag_coverage( flag_OVERSIZE );
4064 for( const trait_id &mut : get_mutations() ) {
4065 apply_mut_encumbrance( vals, mut, oversize );
4066 }
4067}
static const bionic_id bio_shock_absorber("bio_shock_absorber")
static void apply_mut_encumbrance(char_encumbrance_data &vals, const trait_id &mut, const body_part_set &oversize)
Definition: character.cpp:4031

References apply_mut_encumbrance(), bio_shock_absorber, bp_eyes, char_encumbrance_data::elems, exclusive_flag_coverage(), flag_OVERSIZE(), get_bionics(), get_mutations(), and has_active_bionic().

Referenced by calc_encumbrance().

◆ mutate()

void Character::mutate ( )

Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way.

Definition at line 820 of file mutation.cpp.

821{
822 if( get_option<bool>( "BALANCED_MUTATIONS" ) ) {
824 if( !mutagen ) {
825 return;
826 }
827 float mut_power = to_turns<float>( mutagen.get_duration() ) / to_turns<float>
828 ( mutagen.get_int_dur_factor() );
829 add_msg_if_player( m_debug, "Mutation accumulation: %.1f", mut_power );
830 while( mut_power > 1 || roll_remainder( mut_power ) > 0 ) {
831 std::map<trait_id, float> chances = mutation_chances();
832
833 weighted_float_list<trait_id> mutation_picker;
834 for( const auto &p : chances ) {
835 mutation_picker.add( p.first, p.second );
836 }
837
838 for( int tries = 0; tries < 3; tries++ ) {
839 const trait_id *selected = mutation_picker.pick();
840 if( selected == nullptr ) {
841 continue;
842 }
843 add_msg_if_player( m_debug, "Selected mutation %s", selected->obj().name().c_str() );
844 if( has_trait( *selected ) ) {
845 remove_mutation( *selected );
846 break;
847 } else {
848 mutate_towards( *selected );
849 break;
850 }
851 }
852
853 mutagen.mod_duration( -mutagen.get_int_dur_factor() );
854 mut_power -= 1.0f;
855 }
856 } else {
857 old_mutate();
859 }
860}
void remove_mutation(const trait_id &mut, bool silent=false)
Removes a mutation, downgrading to the previous level if possible.
Definition: mutation.cpp:1313
bool mutate_towards(std::vector< trait_id > muts, int num_tries=INT_MAX)
Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.
Definition: mutation.cpp:1072
std::map< trait_id, float > mutation_chances() const
Calculate percentage chances for mutations.
Definition: mutation.cpp:727
void old_mutate()
Definition: mutation.cpp:862
time_duration get_int_dur_factor() const
Returns the number of turns it takes for the intensity to fall by 1 or 0 if intensity isn't based on ...
Definition: effect.cpp:1207
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
T * add(const T &obj, const W &weight)
This will add a new object to the weighted list.
Definition: weighted_list.h:33
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References weighted_list< W, T >::add(), Creature::add_msg_if_player(), effect_accumulated_mutagen, effect::get_duration(), Creature::get_effect(), effect::get_int_dur_factor(), has_trait(), m_debug, effect::mod_duration(), mutate_towards(), mutation_chances(), mutation_branch::name(), old_mutate(), weighted_list< W, T >::pick(), Creature::remove_effect(), remove_mutation(), and roll_remainder().

Referenced by iuse::artifact(), eff_fun_mutating(), hardcoded_effects(), marloss_common(), spell_effect::mutate(), mutate_category(), iuse::mycus(), mattack::science(), iuse::sewage(), suffer_from_artifacts(), suffer_from_other_mutations(), and suffer_from_radiation().

◆ mutate_category()

void Character::mutate_category ( const std::string &  mut_cat)

Picks a random valid mutation in a category and mutate_towards() it.

Definition at line 1019 of file mutation.cpp.

1020{
1021 // Hacky ID comparison is better than separate hardcoded branch used before
1022 // TODO: Turn it into the null id
1023 if( cat == "ANY" ) {
1024 mutate();
1025 return;
1026 }
1027
1028 bool force_bad = one_in( 3 ) && !get_option<bool>( "BALANCED_MUTATIONS" );
1029 bool force_good = false;
1030 if( has_trait( trait_ROBUST ) && force_bad ) {
1031 // Robust Genetics gives you a 33% chance for a good mutation,
1032 // instead of the 33% chance of a bad one.
1033 force_bad = false;
1034 force_good = true;
1035 }
1036 if( has_trait( trait_CHAOTIC_BAD ) ) {
1037 force_bad = true;
1038 force_good = false;
1039 }
1040
1041 // Pull the category's list for valid mutations
1042 std::vector<trait_id> valid = mutations_category[cat];
1043
1044 // Remove anything we already have, that we have a child of, or that
1045 // goes against our intention of a good/bad mutation
1046 for( size_t i = 0; i < valid.size(); i++ ) {
1047 if( !mutation_ok( valid[i], force_good, force_bad ) ) {
1048 valid.erase( valid.begin() + i );
1049 i--;
1050 }
1051 }
1052
1053 mutate_towards( valid, 2 );
1054}
bool mutation_ok(const trait_id &mutation, bool force_good, bool force_bad) const
Returns true if the player doesn't have the mutation or a conflicting one and it complies with the fo...
Definition: mutation.cpp:614
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_ROBUST("ROBUST")
std::map< std::string, std::vector< trait_id > > mutations_category

References has_trait(), mutate(), mutate_towards(), mutation_ok(), mutations_category, one_in(), trait_CHAOTIC_BAD, and trait_ROBUST.

Referenced by eff_fun_rat(), hardcoded_effects(), spell_effect::mutate(), iuse::mycus(), npc::randomize(), mutagen_actor::use(), and mutagen_iv_actor::use().

◆ mutate_towards() [1/2]

bool Character::mutate_towards ( const trait_id mut)

Mutates toward the entered mutation, upgrading or removing conflicts if necessary.

Definition at line 1088 of file mutation.cpp.

1089{
1090 if( has_child_flag( mut ) ) {
1091 remove_child_flag( mut );
1092 return true;
1093 }
1094 const mutation_branch &mdata = mut.obj();
1095
1096 bool has_prereqs = false;
1097 bool prereq1 = false;
1098 bool prereq2 = false;
1099 std::vector<trait_id> canceltrait;
1100 std::vector<trait_id> prereq = mdata.prereqs;
1101 std::vector<trait_id> prereqs2 = mdata.prereqs2;
1102 std::vector<trait_id> cancel = mdata.cancels;
1103 std::vector<trait_id> same_type = get_mutations_in_types( mdata.types );
1104 std::vector<trait_id> all_prereqs = get_all_mutation_prereqs( mut );
1105
1106 // Check mutations of the same type - except for the ones we might need for pre-reqs
1107 for( const auto &consider : same_type ) {
1108 if( std::find( all_prereqs.begin(), all_prereqs.end(), consider ) == all_prereqs.end() ) {
1109 cancel.push_back( consider );
1110 }
1111 }
1112
1113 for( size_t i = 0; i < cancel.size(); i++ ) {
1114 if( !has_trait( cancel[i] ) ) {
1115 cancel.erase( cancel.begin() + i );
1116 i--;
1117 } else if( has_base_trait( cancel[i] ) ) {
1118 //If we have the trait, but it's a base trait, don't allow it to be removed normally
1119 canceltrait.push_back( cancel[i] );
1120 cancel.erase( cancel.begin() + i );
1121 i--;
1122 }
1123 }
1124
1125 for( size_t i = 0; i < cancel.size(); i++ ) {
1126 if( !cancel.empty() ) {
1127 trait_id removed = cancel[i];
1128 remove_mutation( removed );
1129 cancel.erase( cancel.begin() + i );
1130 i--;
1131 // This checks for cases where one trait knocks out several others
1132 // Probably a better way, but gets it Fixed Now--KA101
1133 return mutate_towards( mut );
1134 }
1135 }
1136
1137 for( size_t i = 0; ( !prereq1 ) && i < prereq.size(); i++ ) {
1138 if( has_trait( prereq[i] ) ) {
1139 prereq1 = true;
1140 }
1141 }
1142
1143 for( size_t i = 0; ( !prereq2 ) && i < prereqs2.size(); i++ ) {
1144 if( has_trait( prereqs2[i] ) ) {
1145 prereq2 = true;
1146 }
1147 }
1148
1149 if( prereq1 && prereq2 ) {
1150 has_prereqs = true;
1151 }
1152
1153 if( !has_prereqs && ( !prereq.empty() || !prereqs2.empty() ) ) {
1154 if( !prereq1 && !prereq.empty() ) {
1155 return mutate_towards( prereq );
1156 } else if( !prereq2 && !prereqs2.empty() ) {
1157 return mutate_towards( prereqs2 );
1158 }
1159 }
1160
1161 // Check for threshold mutation, if needed
1162 bool threshold = mdata.threshold;
1163 bool profession = mdata.profession;
1164 bool has_threshreq = false;
1165 std::vector<trait_id> threshreq = mdata.threshreq;
1166
1167 // It shouldn't pick a Threshold anyway--they're supposed to be non-Valid
1168 // and aren't categorized. This can happen if someone makes a threshold mutation into a prerequisite.
1169 if( threshold ) {
1170 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1171 return false;
1172 }
1173 if( profession ) {
1174 // Profession picks fail silently
1175 return false;
1176 }
1177
1178 for( size_t i = 0; !has_threshreq && i < threshreq.size(); i++ ) {
1179 if( has_trait( threshreq[i] ) ) {
1180 has_threshreq = true;
1181 }
1182 }
1183
1184 // No crossing The Threshold by simply not having it
1185 if( !has_threshreq && !threshreq.empty() ) {
1186 add_msg_if_player( _( "You feel something straining deep inside you, yearning to be free…" ) );
1187 return false;
1188 }
1189
1190 // Check if one of the prerequisites that we have TURNS INTO this one
1191 trait_id replacing = trait_id::NULL_ID();
1192 prereq = mdata.prereqs; // Reset it
1193 for( auto &elem : prereq ) {
1194 if( has_trait( elem ) ) {
1195 const trait_id &pre = elem;
1196 const auto &p = pre.obj();
1197 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1198 if( p.replacements[j] == mut ) {
1199 replacing = pre;
1200 }
1201 }
1202 }
1203 }
1204
1205 // Loop through again for prereqs2
1206 trait_id replacing2 = trait_id::NULL_ID();
1207 prereq = mdata.prereqs2; // Reset it
1208 for( auto &elem : prereq ) {
1209 if( has_trait( elem ) ) {
1210 const trait_id &pre2 = elem;
1211 const auto &p = pre2.obj();
1212 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1213 if( p.replacements[j] == mut ) {
1214 replacing2 = pre2;
1215 }
1216 }
1217 }
1218 }
1219
1220 bool mutation_replaced = false;
1221
1222 game_message_type rating;
1223
1224 if( replacing ) {
1225 const auto &replace_mdata = replacing.obj();
1226 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1227 rating = m_mixed;
1228 } else if( replace_mdata.points - mdata.points < 0 ) {
1229 rating = m_good;
1230 } else if( mdata.points - replace_mdata.points < 0 ) {
1231 rating = m_bad;
1232 } else {
1233 rating = m_neutral;
1234 }
1235 //  TODO: Limit this to visible mutations
1236 // TODO: In case invisible mutation turns into visible or vice versa
1237 // print only the visible mutation appearing/disappearing
1238 add_msg_player_or_npc( rating,
1239 _( "Your %1$s mutation turns into %2$s!" ),
1240 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1241 replace_mdata.name(), mdata.name() );
1242
1243 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1244 unset_mutation( replacing );
1245 mutation_replaced = true;
1246 }
1247 if( replacing2 ) {
1248 const auto &replace_mdata = replacing2.obj();
1249 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1250 rating = m_mixed;
1251 } else if( replace_mdata.points - mdata.points < 0 ) {
1252 rating = m_good;
1253 } else if( mdata.points - replace_mdata.points < 0 ) {
1254 rating = m_bad;
1255 } else {
1256 rating = m_neutral;
1257 }
1258 add_msg_player_or_npc( rating,
1259 _( "Your %1$s mutation turns into %2$s!" ),
1260 _( "<npcname>'s %1$s mutation turns into %2$s!" ),
1261 replace_mdata.name(), mdata.name() );
1262 g->events().send<event_type::evolves_mutation>( getID(), replace_mdata.id, mdata.id );
1263 unset_mutation( replacing2 );
1264 mutation_replaced = true;
1265 }
1266 for( const auto &i : canceltrait ) {
1267 const auto &cancel_mdata = i.obj();
1268 if( mdata.mixed_effect || cancel_mdata.mixed_effect ) {
1269 rating = m_mixed;
1270 } else if( mdata.points < cancel_mdata.points ) {
1271 rating = m_bad;
1272 } else if( mdata.points > cancel_mdata.points ) {
1273 rating = m_good;
1274 } else if( mdata.points == cancel_mdata.points ) {
1275 rating = m_neutral;
1276 } else {
1277 rating = m_mixed;
1278 }
1279 // If this new mutation cancels a base trait, remove it and add the mutation at the same time
1280 add_msg_player_or_npc( rating,
1281 _( "Your innate %1$s trait turns into %2$s!" ),
1282 _( "<npcname>'s innate %1$s trait turns into %2$s!" ),
1283 cancel_mdata.name(), mdata.name() );
1284 g->events().send<event_type::evolves_mutation>( getID(), cancel_mdata.id, mdata.id );
1285 unset_mutation( i );
1286 mutation_replaced = true;
1287 }
1288 if( !mutation_replaced ) {
1289 if( mdata.mixed_effect ) {
1290 rating = m_mixed;
1291 } else if( mdata.points > 0 ) {
1292 rating = m_good;
1293 } else if( mdata.points < 0 ) {
1294 rating = m_bad;
1295 } else {
1296 rating = m_neutral;
1297 }
1298 // TODO: Limit to visible mutations
1299 add_msg_player_or_npc( rating,
1300 _( "You gain a mutation called %s!" ),
1301 _( "<npcname> gains a mutation called %s!" ),
1302 mdata.name() );
1303 g->events().send<event_type::gains_mutation>( getID(), mdata.id );
1304 }
1305
1306 set_mutation( mut );
1307
1310 return true;
1311}
static bool same_type(const std::list< item > &items)
void remove_child_flag(const trait_id &flag)
Removes the mutation's child flag from the player's list.
Definition: mutation.cpp:1471
void drench_mut_calc()
Recalculates mutation drench protection for all bodyparts (ignored/good/neutral stats)
Definition: character.cpp:7823
void set_highest_cat_level()
Recalculates mutation_category_level[] values for the player.
Definition: character.cpp:7800
@ cancel
Definition: craft_command.h:28
game_message_type
Definition: enums.h:259
static std::vector< trait_id > get_all_mutation_prereqs(const trait_id &id)
Definition: mutation.cpp:1056
std::vector< trait_id > get_mutations_in_types(const std::set< std::string > &ids)
trait_id id
Definition: mutation.h:76
bool threshold
Definition: mutation.h:83
std::set< std::string > types
Definition: mutation.h:263
bool profession
Definition: mutation.h:85
std::vector< trait_id > threshreq
Definition: mutation.h:262
bool mixed_effect
Definition: mutation.h:91

References _, Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), cancel, mutation_branch::cancels, drench_mut_calc(), evolves_mutation, detail::find(), g, gains_mutation, get_all_mutation_prereqs(), get_mutations_in_types(), getID(), has_base_trait(), has_child_flag(), has_trait(), mutation_branch::id, m_bad, m_good, m_mixed, m_neutral, mutation_branch::mixed_effect, mutate_towards(), mutation_branch::name(), string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), mutation_branch::points, mutation_branch::prereqs, mutation_branch::prereqs2, mutation_branch::profession, remove_child_flag(), remove_mutation(), same_type(), set_highest_cat_level(), set_mutation(), mutation_branch::threshold, mutation_branch::threshreq, mutation_branch::types, and unset_mutation().

◆ mutate_towards() [2/2]

bool Character::mutate_towards ( std::vector< trait_id muts,
int  num_tries = INT_MAX 
)

Mutates toward one of the given mutations, upgrading or removing conflicts if necessary.

Definition at line 1072 of file mutation.cpp.

1073{
1074 while( !muts.empty() && num_tries > 0 ) {
1075 int i = rng( 0, muts.size() - 1 );
1076
1077 if( mutate_towards( muts[i] ) ) {
1078 return true;
1079 }
1080
1081 muts.erase( muts.begin() + i );
1082 --num_tries;
1083 }
1084
1085 return false;
1086}

References mutate_towards(), and rng().

Referenced by mutate(), spell_effect::mutate(), mutate_category(), mutate_towards(), old_mutate(), and debug_menu::wishmutate().

◆ mutation_armor() [1/3]

resistances Character::mutation_armor ( bodypart_id  bp) const

Returns resistances on a body part provided by mutations.

Definition at line 6434 of file character.cpp.

6435{
6436 resistances res;
6437 for( const trait_id &iter : get_mutations() ) {
6438 res += iter->damage_resistance( bp->token );
6439 }
6440
6441 return res;
6442}

References get_mutations().

Referenced by get_all_armor_type(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), mutation_armor(), and passive_absorb_hit().

◆ mutation_armor() [2/3]

float Character::mutation_armor ( bodypart_id  bp,
const damage_unit du 
) const

Definition at line 6449 of file character.cpp.

6450{
6451 return mutation_armor( bp ).get_effective_resist( du );
6452}
float get_effective_resist(const damage_unit &du) const
Definition: damage.cpp:217

References resistances::get_effective_resist(), and mutation_armor().

◆ mutation_armor() [3/3]

float Character::mutation_armor ( bodypart_id  bp,
damage_type  dt 
) const

Definition at line 6444 of file character.cpp.

6445{
6446 return mutation_armor( bp ).type_resist( dt );
6447}
float type_resist(damage_type dt) const
Definition: damage.cpp:213

References mutation_armor(), and resistances::type_resist().

◆ mutation_attacks()

std::vector< special_attack > Character::mutation_attacks ( Creature t) const

Returns a vector of valid mutation attacks.

Unarmed increases chance of attacking with mutated body parts Dexterity increases chance of attacking with mutated body parts

Definition at line 2020 of file melee.cpp.

2021{
2022 std::vector<special_attack> ret;
2023
2024 std::string target = t.disp_name();
2025
2026 const body_part_set usable_body_parts = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
2027 const int unarmed = get_skill_level( skill_unarmed );
2028
2029 for( const trait_id &pr : get_mutations() ) {
2030 const mutation_branch &branch = pr.obj();
2031 for( const mut_attack &mut_atk : branch.attacks_granted ) {
2032 // Covered body part
2033 if( mut_atk.bp != num_bp && !usable_body_parts.test( mut_atk.bp ) ) {
2034 continue;
2035 }
2036
2037 /** @EFFECT_UNARMED increases chance of attacking with mutated body parts */
2038 /** @EFFECT_DEX increases chance of attacking with mutated body parts */
2039
2040 // Calculate actor ability value to be compared against mutation attack difficulty and add debug message
2041 const int proc_value = get_dex() + unarmed;
2042 add_msg( m_debug, "%s proc chance: %d in %d", pr.c_str(), proc_value, mut_atk.chance );
2043 // If the mutation attack fails to proc, bail out
2044 if( !x_in_y( proc_value, mut_atk.chance ) ) {
2045 continue;
2046 }
2047
2048 // If player has any blocker, bail out
2049 if( std::any_of( mut_atk.blocker_mutations.begin(), mut_atk.blocker_mutations.end(),
2050 [this]( const trait_id & blocker ) {
2051 return has_trait( blocker );
2052 } ) ) {
2053 add_msg( m_debug, "%s not procing: blocked", pr.c_str() );
2054 continue;
2055 }
2056
2057 // Player must have all needed traits
2058 if( !std::all_of( mut_atk.required_mutations.begin(), mut_atk.required_mutations.end(),
2059 [this]( const trait_id & need ) {
2060 return has_trait( need );
2061 } ) ) {
2062 add_msg( m_debug, "%s not procing: unmet req", pr.c_str() );
2063 continue;
2064 }
2065
2066 special_attack tmp;
2067 // Ugly special case: player's strings have only 1 variable, NPC have 2
2068 // Can't use <npcname> here
2069 // TODO: Fix
2070 if( is_player() ) {
2071 tmp.text = string_format( _( mut_atk.attack_text_u ), target );
2072 } else {
2073 tmp.text = string_format( _( mut_atk.attack_text_npc ), name, target );
2074 }
2075
2076 // Attack starts here
2077 if( mut_atk.hardcoded_effect ) {
2078 tmp.damage = hardcoded_mutation_attack( *this, pr );
2079 } else {
2080 damage_instance dam = mut_atk.base_damage;
2081 damage_instance scaled = mut_atk.strength_damage;
2082 scaled.mult_damage( std::min<float>( 15.0f, get_str() ), true );
2083 dam.add( scaled );
2084
2085 tmp.damage = dam;
2086 }
2087
2088 if( tmp.damage.total_damage() > 0.0f ) {
2089 ret.emplace_back( tmp );
2090 } else {
2091 add_msg( m_debug, "%s not procing: zero damage", pr.c_str() );
2092 }
2093 }
2094 }
2095
2096 return ret;
2097}
static damage_instance hardcoded_mutation_attack(const Character &u, const trait_id &id)
Definition: melee.cpp:1965
float total_damage() const
Definition: damage.cpp:75
void add(const damage_instance &added_di)
Definition: damage.cpp:93
std::string attack_text_u
Text printed when the attack is proced by you.
Definition: mutation.h:39
std::set< trait_id > blocker_mutations
Need none of those to qualify for this attack.
Definition: mutation.h:45
std::set< trait_id > required_mutations
Need all of those to qualify for this attack.
Definition: mutation.h:43
int chance
Chance to proc is one_in( chance - dex - unarmed )
Definition: mutation.h:51
body_part bp
If not num_bp, this body part needs to be uncovered for the attack to proc.
Definition: mutation.h:48
damage_instance base_damage
Definition: mutation.h:53
bool hardcoded_effect
Should be true when and only when this attack needs hardcoded handling.
Definition: mutation.h:58
damage_instance strength_damage
Multiplied by strength and added to the above.
Definition: mutation.h:55
std::string attack_text_npc
As above, but for npc.
Definition: mutation.h:41
std::vector< mut_attack > attacks_granted
Attacks granted by this mutation.
Definition: mutation.h:252
std::string text
Definition: character.h:197
damage_instance damage
Definition: character.h:198

References _, damage_instance::add(), add_msg(), mut_attack::attack_text_npc, mut_attack::attack_text_u, mutation_branch::attacks_granted, mut_attack::base_damage, mut_attack::blocker_mutations, mut_attack::bp, mut_attack::chance, special_attack::damage, Creature::disp_name(), exclusive_flag_coverage(), get_dex(), get_mutations(), get_skill_level(), get_str(), mut_attack::hardcoded_effect, hardcoded_mutation_attack(), Creature::is_player(), m_debug, damage_instance::mult_damage(), name, num_bp, mut_attack::required_mutations, cata::hash64_detail::ret, skill_unarmed, mut_attack::strength_damage, string_format(), body_part_set::test(), special_attack::text, damage_instance::total_damage(), and x_in_y().

Referenced by perform_special_attacks().

◆ mutation_chances()

std::map< trait_id, float > Character::mutation_chances ( ) const

Calculate percentage chances for mutations.

Definition at line 727 of file mutation.cpp.

728{
729 bool force_bad = false;
730 const bool force_good = false;
732 force_bad = true;
733 }
734
735 int current_score = genetic_score( *this );
736 // 10/10/10/10 in stats, balanced traits, plus tip
737 int expected_score = 4 * 10 + 6;
738 int direction = expected_score - current_score;
739
740 // Duplicates allowed - they'll increase chances of change
741 std::vector<potential_mutation> potential;
742
743 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
744 const trait_id &base_mutation = traits_iter.id;
745 const mutation_branch &base_mdata = traits_iter;
746 bool thresh_save = base_mdata.threshold;
747 bool prof_save = base_mdata.profession;
748 bool purify_save = !base_mdata.purifiable;
749 bool can_remove = !thresh_save && !prof_save && !purify_save;
750
751 if( has_trait( base_mutation ) ) {
752 for( const trait_id &mutation : base_mdata.replacements ) {
753 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
754 potential.emplace_back( base_mutation, mutation, 3 );
755 }
756 }
757
758 for( const trait_id &mutation : base_mdata.additions ) {
759 if( mutation->valid && mutation_ok( mutation, force_good, force_bad ) ) {
760 potential.emplace_back( trait_id::NULL_ID(), mutation, 3 );
761 }
762 }
763
764 // Removal or downgrade (if possible)
765 if( can_remove ) {
766 potential.emplace_back( base_mutation, trait_id::NULL_ID(), 2 );
767 }
768 } else {
769 // Addition from nothing
770 // Duplicates addition above, but that's OK, we need to handle dupes anyway
771 if( base_mutation->valid && mutation_ok( base_mutation, force_good, force_bad ) ) {
772 potential.emplace_back( trait_id::NULL_ID(), base_mutation, 1 );
773 }
774 }
775 }
776
777 // We need all mutation categories in here
778 std::map<std::string, int> padded_mut_cat_lvl = mutation_category_level;
779 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
780 for( const std::string &cat : traits_iter.category ) {
781 // Will do nothing if it exists already
782 padded_mut_cat_lvl.insert( std::make_pair( cat, 0 ) );
783 }
784 }
785
786 const std::map<std::string, float> add_weighs =
787 calc_category_weights( padded_mut_cat_lvl, true );
788 const std::map<std::string, float> rem_weighs =
789 calc_category_weights( padded_mut_cat_lvl, false );
790
791 // Not normalized
792 std::map<trait_id, float> chances;
793
794 // Warning: has duplicates
795 for( const potential_mutation &pm : potential ) {
796 int cost_from = pm.from.is_valid() ? pm.from->cost : 0;
797 int cost_to = pm.to.is_valid() ? pm.to->cost : 0;
798 int score_diff = cost_to - cost_from;
799
800 if( pm.to.is_valid() ) {
801 float cat_mod = std::accumulate( pm.to->category.begin(), pm.to->category.end(), 0.0f,
802 [&add_weighs]( float m, const std::string & cat ) {
803 return std::max( m, add_weighs.at( cat ) );
804 } );
805 float c = score_difference_to_chance( direction + score_diff );
806 chances[pm.to] += c * cat_mod;
807 } else if( pm.from.is_valid() ) {
808 float cat_mod = std::accumulate( pm.from->category.begin(), pm.from->category.end(), 0.0f,
809 [&rem_weighs]( float m, const std::string & cat ) {
810 return std::min( m, rem_weighs.at( cat ) );
811 } );
812 float c = score_difference_to_chance( direction - score_diff );
813 chances[pm.from] += c * cat_mod;
814 }
815 }
816
817 return normalized_map( chances );
818}
direction
Definition: line.h:39
constexpr double c
Definition: magic.cpp:1032
static float score_difference_to_chance(float diff)
Definition: mutation.cpp:665
static T normalized_map(const T &ctn)
Definition: mutation.cpp:674
static int genetic_score(const Character &c)
Definition: mutation.cpp:658
static std::map< std::string, float > calc_category_weights(const std::map< std::string, int > &mcl, bool addition)
Definition: mutation.cpp:694
static const std::vector< mutation_branch > & get_all()
All known mutations.
bool purifiable
Definition: mutation.h:81
std::vector< trait_id > additions
Definition: mutation.h:266

References mutation_branch::additions, c, calc_category_weights(), genetic_score(), mutation_branch::get_all(), has_trait(), string_id< T >::id(), mutation_category_level, mutation_ok(), normalized_map(), string_id< mutation_branch >::NULL_ID(), mutation_branch::profession, mutation_branch::purifiable, mutation_branch::replacements, score_difference_to_chance(), mutation_branch::threshold, trait_CHAOTIC_BAD, and mutation_branch::valid.

Referenced by debug_menu::debug(), and mutate().

◆ mutation_effect()

void Character::mutation_effect ( const trait_id mut)

Handles things like removal of armor, etc.

Definition at line 256 of file mutation.cpp.

257{
258 if( mut == trait_GLASSJAW ) {
259 recalc_hp();
260
261 } else if( mut == trait_STR_ALPHA ) {
262 if( str_max < 16 ) {
263 str_max = 8 + str_max / 2;
264 }
265 apply_mods( mut, true );
266 recalc_hp();
267 } else if( mut == trait_DEX_ALPHA ) {
268 if( dex_max < 16 ) {
269 dex_max = 8 + dex_max / 2;
270 }
271 apply_mods( mut, true );
272 } else if( mut == trait_INT_ALPHA ) {
273 if( int_max < 16 ) {
274 int_max = 8 + int_max / 2;
275 }
276 apply_mods( mut, true );
277 } else if( mut == trait_INT_SLIME ) {
278 int_max *= 2; // Now, can you keep it? :-)
279
280 } else if( mut == trait_PER_ALPHA ) {
281 if( per_max < 16 ) {
282 per_max = 8 + per_max / 2;
283 }
284 apply_mods( mut, true );
285 } else {
286 apply_mods( mut, true );
287 }
288
290
291 const auto &branch = mut.obj();
292 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
293 branch.hp_adjustment != 0.0f ) {
294 recalc_hp();
295 }
296
297 remove_worn_items_with( [&]( item & armor ) {
298 static const std::string mutation_safe = "OVERSIZE";
299 if( armor.has_flag( mutation_safe ) ) {
300 return false;
301 }
302 if( !branch.conflicts_with_item( armor ) ) {
303 return false;
304 }
305
307 _( "Your %s is pushed off!" ),
308 _( "<npcname>'s %s is pushed off!" ),
309 armor.tname() );
310 get_map().add_item_or_charges( pos(), armor );
311 return true;
312 } );
313
314 if( branch.starts_active ) {
315 my_mutations[mut].powered = true;
316 }
317
318 on_mutation_gain( mut );
319}
std::list< item > remove_worn_items_with(std::function< bool(item &)> filter)
Similar to remove_items_with, but considers only worn items and not their content (item::contents is ...
Definition: character.cpp:2295
static const trait_id trait_PER_ALPHA("PER_ALPHA")
static const trait_id trait_STR_ALPHA("STR_ALPHA")
static const trait_id trait_GLASSJAW("GLASSJAW")
static const trait_id trait_DEX_ALPHA("DEX_ALPHA")
static const trait_id trait_INT_SLIME("INT_SLIME")
static const trait_id trait_INT_ALPHA("INT_ALPHA")

References _, Creature::add_msg_player_or_npc(), apply_mods(), dex_max, get_map(), item::has_flag(), int_max, m_bad, my_mutations, string_id< T >::obj(), on_mutation_gain(), per_max, pos(), recalc_hp(), recalculate_size(), remove_worn_items_with(), str_max, item::tname(), trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_wear(), set_mutation(), and switch_mutations().

◆ mutation_loss_effect()

void Character::mutation_loss_effect ( const trait_id mut)

Handles what happens when you lose a mutation.

Definition at line 321 of file mutation.cpp.

322{
323 if( mut == trait_GLASSJAW ) {
324 recalc_hp();
325
326 } else if( mut == trait_STR_ALPHA ) {
327 apply_mods( mut, false );
328 if( str_max < 16 ) {
329 str_max = 2 * ( str_max - 8 );
330 }
331 recalc_hp();
332 } else if( mut == trait_DEX_ALPHA ) {
333 apply_mods( mut, false );
334 if( dex_max < 16 ) {
335 dex_max = 2 * ( dex_max - 8 );
336 }
337 } else if( mut == trait_INT_ALPHA ) {
338 apply_mods( mut, false );
339 if( int_max < 16 ) {
340 int_max = 2 * ( int_max - 8 );
341 }
342 } else if( mut == trait_INT_SLIME ) {
343 int_max /= 2; // In case you have a freak accident with the debug menu ;-)
344
345 } else if( mut == trait_PER_ALPHA ) {
346 apply_mods( mut, false );
347 if( per_max < 16 ) {
348 per_max = 2 * ( per_max - 8 );
349 }
350 } else {
351 apply_mods( mut, false );
352 }
353
355
356 const auto &branch = mut.obj();
357 if( branch.hp_modifier != 0.0f || branch.hp_modifier_secondary != 0.0f ||
358 branch.hp_adjustment != 0.0f ) {
359 recalc_hp();
360 }
361
362 on_mutation_loss( mut );
363}
void on_mutation_loss(const trait_id &mid)
Called when a mutation is lost.
Definition: character.cpp:9908

References apply_mods(), dex_max, int_max, string_id< T >::obj(), on_mutation_loss(), per_max, recalc_hp(), recalculate_size(), str_max, trait_DEX_ALPHA, trait_GLASSJAW, trait_INT_ALPHA, trait_INT_SLIME, trait_PER_ALPHA, and trait_STR_ALPHA.

Referenced by on_item_takeoff(), switch_mutations(), and unset_mutation().

◆ mutation_ok()

bool Character::mutation_ok ( const trait_id mutation,
bool  force_good,
bool  force_bad 
) const

Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing.

Definition at line 614 of file mutation.cpp.

615{
616 if( !is_category_allowed( mutation->category ) ) {
617 return false;
618 }
619 if( mutation_branch::trait_is_blacklisted( mutation ) ) {
620 return false;
621 }
622 if( has_trait( mutation ) || has_child_flag( mutation ) ) {
623 // We already have this mutation or something that replaces it.
624 return false;
625 }
626
627 for( const bionic_id &bid : get_bionics() ) {
628 for( const trait_id &mid : bid->canceled_mutations ) {
629 if( mid == mutation ) {
630 return false;
631 }
632 }
633 }
634
635 const mutation_branch &mdata = mutation.obj();
636 if( force_bad && mdata.points > 0 ) {
637 // This is a good mutation, and we're due for a bad one.
638 return false;
639 }
640
641 if( force_good && mdata.points < 0 ) {
642 // This is a bad mutation, and we're due for a good one.
643 return false;
644 }
645
646 return true;
647}
bool is_category_allowed(const std::vector< std::string > &category) const
Returns true if this category of mutation is allowed.
Definition: mutation.cpp:371
std::vector< std::string > category
Definition: mutation.h:267
static bool trait_is_blacklisted(const trait_id &tid)
Check if the trait with the given ID is blacklisted.

References mutation_branch::category, get_bionics(), has_child_flag(), has_trait(), is_category_allowed(), string_id< T >::obj(), mutation_branch::points, and mutation_branch::trait_is_blacklisted().

Referenced by mutate_category(), mutation_chances(), and old_mutate().

◆ mutation_spend_resources()

void Character::mutation_spend_resources ( const trait_id mut)

Removes the appropriate costs (NOTE: will reapply mods & recalc sightlines in case of newly activated mutation).

Definition at line 1698 of file mutation.cpp.

1699{
1700 const mutation_branch &mdata = mut.obj();
1701 char_trait_data &tdata = my_mutations[mut];
1702 int cost = mdata.cost;
1703 if( tdata.powered && tdata.charge > 0 ) {
1704 // Already-on units just lose a bit of charge
1705 tdata.charge--;
1706 } else {
1707 // Not-on units, or those with zero charge, have to pay the power cost
1708 if( mdata.cooldown > 0 ) {
1709 tdata.charge = mdata.cooldown - 1;
1710 }
1711 if( mdata.hunger ) {
1712 // burn some energy
1713 mod_stored_kcal( -cost * 6 );
1714 }
1715 if( mdata.thirst ) {
1716 mod_thirst( cost );
1717 }
1718 if( mdata.fatigue ) {
1719 mod_fatigue( cost );
1720 }
1721
1722 // Handle stat changes from activation
1723 apply_mods( mut, true );
1725 }
1726}
int charge
Time (in turns) until the mutation increase hunger/thirst/fatigue according to its cost (mutation_bra...
Definition: character.h:218

References apply_mods(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, mutation_branch::fatigue, mutation_branch::hunger, mod_fatigue(), mod_stored_kcal(), mod_thirst(), my_mutations, string_id< T >::obj(), char_trait_data::powered, recalc_sight_limits(), and mutation_branch::thirst.

Referenced by activate_mutation(), iexamine::ledge(), and game::vertical_move().

◆ mutation_value()

float Character::mutation_value ( const std::string &  val) const

Goes over all mutations, gets min and max of a value with given name.

Returns
min( 0, lowest ) + max( 0, highest )

Definition at line 6650 of file character.cpp.

6651{
6652 // Syntax similar to tuple get<n>()
6653 const auto found = mutation_value_map.find( val );
6654
6655 if( found == mutation_value_map.end() ) {
6656 debugmsg( "Invalid mutation value name %s", val );
6657 return 0.0f;
6658 } else {
6659 return found->second( cached_mutations );
6660 }
6661}
static const std::map< std::string, std::function< float(std::vector< const mutation_branch * >)> > mutation_value_map
Definition: character.cpp:6612

References cached_mutations, debugmsg, and mutation_value_map.

Referenced by attack_cost(), body_window(), calc_needs_rates(), draw_limb_health(), draw_speed_tab(), get_stamina_max(), healing_rate(), healing_rate_medicine(), hearing_ability(), is_immune_effect(), known_magic::mana_regen_rate(), known_magic::max_mana(), metabolic_rate_base(), overmap_sight_range(), read_speed(), recalc_hp(), recalc_speed_bonus(), regen(), reset_stats(), run_cost(), rust_rate(), swim_speed(), update_stamina(), visibility(), game::walk_move(), and weight_capacity().

◆ natural_attack_restricted_on()

bool Character::natural_attack_restricted_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body_part, ignoring items with the ALLOWS_NATURAL_ATTACKS flag.

Definition at line 1783 of file character.cpp.

1784{
1785 for( const item &i : worn ) {
1786 if( i.covers( bp->token ) && !i.has_flag( "ALLOWS_NATURAL_ATTACKS" ) &&
1787 !i.has_flag( "SEMITANGIBLE" ) &&
1788 !i.has_flag( "PERSONAL" ) && !i.has_flag( "AURA" ) ) {
1789 return true;
1790 }
1791 }
1792 return false;
1793}

References worn.

Referenced by roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

◆ nearby()

std::vector< item_location > Character::nearby ( const std::function< bool(const item *, const item *)> &  func,
int  radius = 1 
) const

Returns nearby items which match the provided predicate.

Definition at line 2199 of file character.cpp.

2201{
2202 std::vector<item_location> res;
2203
2204 visit_items( [&]( const item * e, const item * parent ) {
2205 if( func( e, parent ) ) {
2206 res.emplace_back( const_cast<Character &>( *this ), const_cast<item *>( e ) );
2207 }
2208 return VisitResponse::NEXT;
2209 } );
2210
2211 for( const auto &cur : map_selector( pos(), radius ) ) {
2212 cur.visit_items( [&]( const item * e, const item * parent ) {
2213 if( func( e, parent ) ) {
2214 res.emplace_back( cur, const_cast<item *>( e ) );
2215 }
2216 return VisitResponse::NEXT;
2217 } );
2218 }
2219
2220 for( const auto &cur : vehicle_selector( pos(), radius ) ) {
2221 cur.visit_items( [&]( const item * e, const item * parent ) {
2222 if( func( e, parent ) ) {
2223 res.emplace_back( cur, const_cast<item *>( e ) );
2224 }
2225 return VisitResponse::NEXT;
2226 } );
2227 }
2228
2229 return res;
2230}

References NEXT, pos(), and visitable< Character >::visit_items().

Referenced by bandolier_actor::reload(), and npc::within_boundaries_of_camp().

◆ nutrition_for()

int Character::nutrition_for ( const item comest) const

Handles the nutrition value for a comestible.

Definition at line 467 of file consumption.cpp.

468{
470}
static constexpr float kcal_per_nutr
1 nutr ~= 8.7kcal (1 nutr/5min = 288 nutr/day at 2500kcal/day)
Definition: itype.h:181
int kcal
amount of kcal this food has
Definition: stomach.h:18

References compute_effective_nutrients(), nutrients::kcal, and islot_comestible::kcal_per_nutr.

Referenced by iuse::blech(), consume_effects(), npc::decide_needs(), eat(), iuse::plantblech(), and npc::value().

◆ old_mutate()

void Character::old_mutate ( )
private

Definition at line 862 of file mutation.cpp.

863{
864 bool force_bad = one_in( 3 );
865 bool force_good = false;
866 if( has_trait( trait_ROBUST ) && force_bad ) {
867 // Robust Genetics gives you a 33% chance for a good mutation,
868 // instead of the 33% chance of a bad one.
869 force_bad = false;
870 force_good = true;
871 }
873 force_bad = true;
874 force_good = false;
875 }
876
877 // Determine the highest mutation category
878 std::string cat = get_highest_category();
879
880 if( !is_category_allowed( cat ) ) {
881 cat.clear();
882 }
883
884 // See if we should upgrade/extend an existing mutation...
885 std::vector<trait_id> upgrades;
886
887 // ... or remove one that is not in our highest category
888 std::vector<trait_id> downgrades;
889
890 // For each mutation...
891 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
892 const trait_id &base_mutation = traits_iter.id;
893 const mutation_branch &base_mdata = traits_iter;
894 bool thresh_save = base_mdata.threshold;
895 bool prof_save = base_mdata.profession;
896 // are we unpurifiable? (saved from mutating away)
897 bool purify_save = !base_mdata.purifiable;
898
899 // ...that we have...
900 if( has_trait( base_mutation ) ) {
901 // ...consider the mutations that replace it.
902 for( const trait_id &mutation : base_mdata.replacements ) {
903 bool valid_ok = mutation->valid;
904
905 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
906 ( valid_ok ) ) {
907 upgrades.push_back( mutation );
908 }
909 }
910
911 // ...consider the mutations that add to it.
912 for( const trait_id &mutation : base_mdata.additions ) {
913 bool valid_ok = mutation->valid;
914
915 if( ( mutation_ok( mutation, force_good, force_bad ) ) &&
916 ( valid_ok ) ) {
917 upgrades.push_back( mutation );
918 }
919 }
920
921 // ...consider whether its in our highest category
922 if( has_trait( base_mutation ) && !has_base_trait( base_mutation ) ) {
923 // Starting traits don't count toward categories
924 std::vector<trait_id> group = mutations_category[cat];
925 bool in_cat = false;
926 for( const trait_id &elem : group ) {
927 if( elem == base_mutation ) {
928 in_cat = true;
929 break;
930 }
931 }
932
933 // mark for removal
934 // no removing Thresholds/Professions this way!
935 // unpurifiable traits also cannot be purified
936 if( !in_cat && !thresh_save && !prof_save && !purify_save ) {
937 if( one_in( 4 ) ) {
938 downgrades.push_back( base_mutation );
939 }
940 }
941 }
942 }
943 }
944
945 // Preliminary round to either upgrade or remove existing mutations
946 if( one_in( 2 ) ) {
947 if( !upgrades.empty() ) {
948 // (upgrade count) chances to pick an upgrade, 4 chances to pick something else.
949 size_t roll = rng( 0, upgrades.size() + 4 );
950 if( roll < upgrades.size() ) {
951 // We got a valid upgrade index, so use it and return.
952 mutate_towards( upgrades[roll] );
953 return;
954 }
955 }
956 } else {
957 // Remove existing mutations that don't fit into our category
958 if( !downgrades.empty() && !cat.empty() ) {
959 size_t roll = rng( 0, downgrades.size() + 4 );
960 if( roll < downgrades.size() ) {
961 remove_mutation( downgrades[roll] );
962 return;
963 }
964 }
965 }
966
967 std::vector<trait_id> valid; // Valid mutations
968 bool first_pass = true;
969
970 do {
971 // If we tried once with a non-NULL category, and couldn't find anything valid
972 // there, try again with empty category
973 // CHAOTIC_BAD lets the game pull from any category by default
974 if( !first_pass || has_trait( trait_CHAOTIC_BAD ) ) {
975 cat.clear();
976 }
977
978 if( cat.empty() ) {
979 // Pull the full list
980 for( const mutation_branch &traits_iter : mutation_branch::get_all() ) {
981 if( traits_iter.valid && is_category_allowed( traits_iter.category ) ) {
982 valid.push_back( traits_iter.id );
983 }
984 }
985 } else {
986 // Pull the category's list
987 valid = mutations_category[cat];
988 }
989
990 // Remove anything we already have, that we have a child of, or that
991 // goes against our intention of a good/bad mutation
992 for( size_t i = 0; i < valid.size(); i++ ) {
993 if( ( !mutation_ok( valid[i], force_good, force_bad ) ) ||
994 ( !valid[i]->valid ) ) {
995 valid.erase( valid.begin() + i );
996 i--;
997 }
998 }
999
1000 if( valid.empty() ) {
1001 // So we won't repeat endlessly
1002 first_pass = false;
1003 }
1004 } while( valid.empty() && !cat.empty() );
1005
1006 if( valid.empty() ) {
1007 // Couldn't find anything at all!
1008 return;
1009 }
1010
1011 if( mutate_towards( random_entry( valid ) ) ) {
1012 return;
1013 } else {
1014 // if mutation failed (errors, post-threshold pick), try again once.
1015 mutate_towards( random_entry( valid ) );
1016 }
1017}
group
Definition: sounds.h:125

References mutation_branch::additions, mutation_branch::get_all(), get_highest_category(), has_base_trait(), has_trait(), string_id< T >::id(), is_category_allowed(), mutate_towards(), mutation_ok(), mutations_category, one_in(), mutation_branch::profession, mutation_branch::purifiable, random_entry(), remove_mutation(), mutation_branch::replacements, rng(), mutation_branch::threshold, trait_CHAOTIC_BAD, trait_ROBUST, and mutation_branch::valid.

Referenced by mutate().

◆ on_damage_of_type()

void Character::on_damage_of_type ( int  adjusted_damage,
damage_type  type,
const bodypart_id bp 
)
overrideprotectedvirtual

Reimplemented from Creature.

Definition at line 4520 of file character.cpp.

4521{
4522 // Electrical damage has a chance to temporarily incapacitate bionics in the damaged body_part.
4523 if( type == DT_ELECTRIC ) {
4524 const time_duration min_disable_time = 10_turns * adjusted_damage;
4525 for( bionic &i : *my_bionics ) {
4526 if( !i.powered ) {
4527 // Unpowered bionics are protected from power surges.
4528 continue;
4529 }
4530 const auto &info = i.info();
4531 if( info.has_flag( STATIC( flag_str_id( "BIONIC_SHOCKPROOF" ) ) )
4532 || info.has_flag( STATIC( flag_str_id( "BIONIC_FAULTY" ) ) ) ) {
4533 continue;
4534 }
4535 const std::map<bodypart_str_id, int> &bodyparts = info.occupied_bodyparts;
4536 if( bodyparts.find( bp.id() ) != bodyparts.end() ) {
4537 const int bp_hp = get_part_hp_cur( bp );
4538 // The chance to incapacitate is as high as 50% if the attack deals damage equal to one third of the body part's current health.
4539 if( x_in_y( adjusted_damage * 3, bp_hp ) && one_in( 2 ) ) {
4540 if( i.incapacitated_time == 0_turns ) {
4541 add_msg_if_player( m_bad, _( "Your %s bionic shorts out!" ), info.name );
4542 }
4543 i.incapacitated_time += rng( min_disable_time, 10 * min_disable_time );
4544 }
4545 }
4546 }
4547 }
4548}
#define STATIC(expr)
The purpose of this macro is to provide a concise syntax for creation of inline literals (std::string...
Definition: make_static.h:24
string_id< json_flag > flag_str_id
Definition: type_id.h:213

References _, Creature::add_msg_if_player(), DT_ELECTRIC, Creature::get_part_hp_cur(), int_id< T >::id(), m_bad, my_bionics, one_in(), rng(), STATIC, type, and x_in_y().

◆ on_dodge()

void Character::on_dodge ( Creature source,
int  difficulty 
)
overridevirtual

This creature just dodged an attack - possibly special/ranged attack - from source.

Players should train dodge, monsters may use some special defenses.

Reimplemented from Creature.

Definition at line 8263 of file character.cpp.

8264{
8265 static const matec_id tec_none( "tec_none" );
8266
8267 // Each avoided hit consumes an available dodge
8268 // When no more available we are likely to fail player::dodge_roll
8269 dodges_left--;
8270
8271 // dodging throws of our aim unless we are either skilled at dodging or using a small weapon
8272 const item &weapon = primary_weapon();
8273 if( is_armed() && weapon.is_gun() ) {
8274 recoil += std::max( weapon.volume() / 250_ml - get_skill_level( skill_dodge ), 0 ) * rng( 0, 100 );
8275 recoil = std::min( MAX_RECOIL, recoil );
8276 }
8277
8278 // Even if we are not to train still call practice to prevent skill rust
8279 difficulty = std::max( difficulty, 0 );
8280 as_player()->practice( skill_dodge, difficulty * 2, difficulty );
8281
8282 martial_arts_data->ma_ondodge_effects( *this );
8283
8284 // For adjacent attackers check for techniques usable upon successful dodge
8285 if( source && square_dist( pos(), source->pos() ) == 1 ) {
8286 matec_id tec = pick_technique( *source, primary_weapon(), false, true, false );
8287
8288 if( tec != tec_none && !is_dead_state() ) {
8289 if( get_stamina() < get_stamina_max() / 3 ) {
8290 add_msg( m_bad, _( "You try to counterattack but you are too exhausted!" ) );
8291 } else {
8292 melee_attack( *source, false, &tec );
8293 }
8294 }
8295 }
8296}

References _, add_msg(), Creature::as_player(), dodges_left, get_skill_level(), get_stamina(), get_stamina_max(), is_armed(), is_dead_state(), item::is_gun(), m_bad, martial_arts_data, MAX_RECOIL, melee_attack(), pick_technique(), Creature::pos(), pos(), practice(), primary_weapon(), recoil, rng(), skill_dodge, square_dist(), tec_none, and item::volume().

Referenced by mattack::grab().

◆ on_effect_int_change()

void Character::on_effect_int_change ( const efftype_id effect_type,
int  intensity,
const bodypart_str_id bp 
)
overridevirtual

Called when effect intensity has been changed.

Reimplemented from Creature.

Definition at line 9887 of file character.cpp.

9889{
9890 // Adrenaline can reduce perceived pain (or increase it when you enter comedown).
9891 // See @ref get_perceived_pain()
9893 // Note that calling this does no harm if it wasn't changed.
9894 on_stat_change( "perceived_pain", get_perceived_pain() );
9895 }
9896
9897 morale->on_effect_int_change( effect_type, intensity, bp );
9898}

References effect_adrenaline, get_perceived_pain(), morale, and on_stat_change().

Referenced by load().

◆ on_hit()

void Character::on_hit ( Creature source,
bodypart_id  bp_hit,
dealt_projectile_attack const *  proj 
)
overridevirtual

This creature just got hit by an attack - possibly special/ranged attack - from source.

Parameters
sourceSource creature, can be nullptr
projSource projectile, can be nullptr Players should train dodge, possibly counter-attack somehow.

Implements Creature.

Definition at line 8303 of file character.cpp.

8305{
8307 if( source == nullptr || proj != nullptr ) {
8308 return;
8309 }
8310
8311 bool u_see = g->u.sees( *this );
8312 units::energy trigger_cost_base = bio_ods->power_trigger;
8313 if( has_active_bionic( bio_ods ) && get_power_level() >= trigger_cost_base * 4 ) {
8314 if( is_player() ) {
8315 add_msg( m_good, _( "Your offensive defense system shocks %s in mid-attack!" ),
8316 source->disp_name() );
8317 } else if( u_see ) {
8318 add_msg( _( "%1$s's offensive defense system shocks %2$s in mid-attack!" ),
8319 disp_name(),
8320 source->disp_name() );
8321 }
8322 int shock = rng( 1, 4 );
8323 mod_power_level( -shock * trigger_cost_base );
8324 damage_instance ods_shock_damage;
8325 ods_shock_damage.add_damage( DT_ELECTRIC, shock * 5 );
8326 // Should hit body part used for attack
8327 source->deal_damage( this, bodypart_id( "torso" ), ods_shock_damage );
8328 }
8329 if( !wearing_something_on( bp_hit ) &&
8331 int spine = rng( 1, has_trait( trait_QUILLS ) ? 20 : 8 );
8332 if( !is_player() ) {
8333 if( u_see ) {
8334 add_msg( _( "%1$s's %2$s puncture %3$s in mid-attack!" ), name,
8335 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8336 source->disp_name() );
8337 }
8338 } else {
8339 add_msg( m_good, _( "Your %1$s puncture %2$s in mid-attack!" ),
8340 ( has_trait( trait_QUILLS ) ? _( "quills" ) : _( "spines" ) ),
8341 source->disp_name() );
8342 }
8343 damage_instance spine_damage;
8344 spine_damage.add_damage( DT_STAB, spine );
8345 source->deal_damage( this, bodypart_id( "torso" ), spine_damage );
8346 }
8347 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_THORNS ) ) &&
8348 ( !( source->has_weapon() ) ) ) {
8349 if( !is_player() ) {
8350 if( u_see ) {
8351 add_msg( _( "%1$s's %2$s scrape %3$s in mid-attack!" ), name,
8352 _( "thorns" ), source->disp_name() );
8353 }
8354 } else {
8355 add_msg( m_good, _( "Your thorns scrape %s in mid-attack!" ), source->disp_name() );
8356 }
8357 int thorn = rng( 1, 4 );
8358 damage_instance thorn_damage;
8359 thorn_damage.add_damage( DT_CUT, thorn );
8360 // In general, critters don't have separate limbs
8361 // so safer to target the torso
8362 source->deal_damage( this, bodypart_id( "torso" ), thorn_damage );
8363 }
8364 if( ( !( wearing_something_on( bp_hit ) ) ) && ( has_trait( trait_CF_HAIR ) ) ) {
8365 if( !is_player() ) {
8366 if( u_see ) {
8367 add_msg( _( "%1$s gets a load of %2$s's %3$s stuck in!" ), source->disp_name(),
8368 name, ( _( "hair" ) ) );
8369 }
8370 } else {
8371 add_msg( m_good, _( "Your hairs detach into %s!" ), source->disp_name() );
8372 }
8373 source->add_effect( effect_stunned, 2_turns );
8374 if( one_in( 3 ) ) { // In the eyes!
8375 source->add_effect( effect_blind, 2_turns );
8376 }
8377 }
8378 if( worn_with_flag( "REQUIRES_BALANCE" ) && !has_effect( effect_downed ) ) {
8379 int rolls = 4;
8380 if( worn_with_flag( "ROLLER_ONE" ) ) {
8381 rolls += 2;
8382 }
8383 if( has_trait( trait_PROF_SKATER ) ) {
8384 rolls--;
8385 }
8386 if( has_trait( trait_DEFT ) ) {
8387 rolls--;
8388 }
8389
8390 if( stability_roll() < dice( rolls, 10 ) ) {
8391 if( !is_player() ) {
8392 if( u_see ) {
8393 add_msg( _( "%1$s loses their balance while being hit!" ), name );
8394 }
8395 } else {
8396 add_msg( m_bad, _( "You lose your balance while being hit!" ) );
8397 }
8398 // This kind of downing is not subject to immunity.
8399 add_effect( effect_downed, 2_turns, num_bp, 0, true );
8400 }
8401 }
8402 enchantment_cache->cast_hit_me( *this, source );
8403}
static const trait_id trait_CF_HAIR("CF_HAIR")
static const trait_id trait_QUILLS("QUILLS")
static const trait_id trait_SPINES("SPINES")
static const bionic_id bio_ods("bio_ods")
static const trait_id trait_THORNS("THORNS")
static const trait_id trait_DEFT("DEFT")
static const trait_id trait_PROF_SKATER("PROF_SKATER")
float stability_roll() const override
Returns value of player's stable footing.
virtual bool has_weapon() const =0

References _, damage_instance::add_damage(), Creature::add_effect(), add_msg(), bio_ods, Creature::check_dead_state(), Creature::deal_damage(), dice(), Creature::disp_name(), disp_name(), DT_CUT, DT_ELECTRIC, DT_STAB, effect_blind, effect_downed, effect_stunned, enchantment_cache, g, get_power_level(), has_active_bionic(), Creature::has_effect(), has_trait(), Creature::has_weapon(), Creature::is_player(), m_bad, m_good, mod_power_level(), name, num_bp, one_in(), bionic_data::power_trigger, rng(), stability_roll(), trait_CF_HAIR, trait_DEFT, trait_PROF_SKATER, trait_QUILLS, trait_SPINES, trait_THORNS, wearing_something_on(), and worn_with_flag().

Referenced by melee_attack().

◆ on_hurt()

void Character::on_hurt ( Creature source,
bool  disturb = true 
)

Handles effects that happen when the player is damaged and aware of the fact.

Definition at line 8699 of file character.cpp.

8700{
8702 ( get_part_hp_cur( bodypart_id( "head" ) ) < 25 ||
8703 get_part_hp_cur( bodypart_id( "torso" ) ) < 15 ) ) {
8704 add_effect( effect_adrenaline, 20_minutes );
8705 }
8706
8707 if( disturb ) {
8709 wake_up();
8710 }
8711 if( !is_npc() && !has_effect( effect_narcosis ) ) {
8712 if( source != nullptr ) {
8713 g->cancel_activity_or_ignore_query( distraction_type::attacked,
8714 string_format( _( "You were attacked by %s!" ),
8715 source->disp_name() ) );
8716 } else {
8717 g->cancel_activity_or_ignore_query( distraction_type::attacked, _( "You were hurt!" ) );
8718 }
8719 }
8720 }
8721}
static const trait_id trait_ADRENALINE("ADRENALINE")

References _, Creature::add_effect(), attacked, Creature::disp_name(), effect_adrenaline, effect_narcosis, effect_sleep, g, Creature::get_part_hp_cur(), Creature::has_effect(), has_trait(), Creature::is_npc(), string_format(), trait_ADRENALINE, and wake_up().

Referenced by apply_damage(), deal_damage(), and hurtall().

◆ on_item_takeoff()

void Character::on_item_takeoff ( const item it)

Called when an item is taken off.

Definition at line 9874 of file character.cpp.

9875{
9876 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9877 mutation_loss_effect( mut );
9880 if( get_stamina() > get_stamina_max() ) {
9882 }
9883 }
9884 morale->on_item_takeoff( it );
9885}
void mutation_loss_effect(const trait_id &mut)
Handles what happens when you lose a mutation.
Definition: mutation.cpp:321
std::vector< trait_id > mutations_from_wearing(const Character &guy) const
Definition: item.cpp:9083

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_loss_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by item::on_takeoff().

◆ on_item_wear()

void Character::on_item_wear ( const item it)

Called when an item is worn.

Definition at line 9859 of file character.cpp.

9860{
9861 for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
9862 mutation_effect( mut );
9865
9866 // If the stamina is higher than the max (Languorous), set it back to max
9867 if( get_stamina() > get_stamina_max() ) {
9869 }
9870 }
9871 morale->on_item_wear( it );
9872}
void mutation_effect(const trait_id &mut)
Handles things like removal of armor, etc.
Definition: mutation.cpp:256

References calc_encumbrance(), get_stamina(), get_stamina_max(), morale, mutation_effect(), item::mutations_from_wearing(), recalc_sight_limits(), and set_stamina().

Referenced by debug_menu::character_edit_menu(), load(), and item::on_wear().

◆ on_mutation_gain()

void Character::on_mutation_gain ( const trait_id mid)

Called when a mutation is gained.

Definition at line 9900 of file character.cpp.

9901{
9902 morale->on_mutation_gain( mid );
9903 magic->on_mutation_gain( mid, *this );
9904 update_type_of_scent( mid );
9905 recalculate_enchantment_cache(); // mutations can have enchantments
9906}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by add_bionic(), known_magic::learn_spell(), load(), and mutation_effect().

◆ on_mutation_loss()

void Character::on_mutation_loss ( const trait_id mid)

Called when a mutation is lost.

Definition at line 9908 of file character.cpp.

9909{
9910 morale->on_mutation_loss( mid );
9911 magic->on_mutation_loss( mid );
9912 update_type_of_scent( mid, false );
9913 recalculate_enchantment_cache(); // mutations can have enchantments
9914}

References magic, morale, recalculate_enchantment_cache(), and update_type_of_scent().

Referenced by mutation_loss_effect().

◆ on_stat_change()

void Character::on_stat_change ( const std::string &  stat,
int  value 
)
overridevirtual

Called when a stat is changed.

Reimplemented from Creature.

Definition at line 9916 of file character.cpp.

9917{
9918 morale->on_stat_change( stat, value );
9919}

References morale.

Referenced by load(), on_effect_int_change(), set_fatigue(), set_pain(), set_painkiller(), and set_thirst().

◆ on_worn_item_transform()

void Character::on_worn_item_transform ( const item old_it,
const item new_it 
)

Called when a worn item is transformed.

Definition at line 9921 of file character.cpp.

9922{
9923 morale->on_worn_item_transform( old_it, new_it );
9924}

References morale.

Referenced by iuse_transform::use().

◆ on_worn_item_washed()

void Character::on_worn_item_washed ( const item it)

Called when an item is washed.

Definition at line 9852 of file character.cpp.

9853{
9854 if( is_worn( it ) ) {
9855 morale->on_worn_item_washed( it );
9856 }
9857}

References is_worn(), and morale.

Referenced by wash_activity_actor::finish().

◆ operator=() [1/2]

Character & Character::operator= ( Character &&  )
protecteddefault

◆ operator=() [2/2]

Character & Character::operator= ( const Character )
delete

◆ overmap_los()

bool Character::overmap_los ( const tripoint_abs_omt omt,
int  sight_points 
)

Returns true if overmap tile is within player line-of-sight.

Definition at line 635 of file character.cpp.

636{
638 const point_rel_omt offset = omt.xy() - ompos.xy();
639 if( offset.x() < -sight_points || offset.x() > sight_points ||
640 offset.y() < -sight_points || offset.y() > sight_points ) {
641 // Outside maximum sight range
642 return false;
643 }
644
645 // TODO: fix point types
646 const std::vector<tripoint> line = line_to( ompos.raw(), omt.raw(), 0, 0 );
647 for( size_t i = 0; i < line.size() && sight_points >= 0; i++ ) {
648 const tripoint &pt = line[i];
649 const oter_id &ter = overmap_buffer.ter( tripoint_abs_omt( pt ) );
650 sight_points -= static_cast<int>( ter->get_see_cost() );
651 if( sight_points < 0 ) {
652 return false;
653 }
654 }
655 return true;
656}
constexpr auto & x()
Definition: coordinates.h:118
constexpr Point & raw()
Definition: coordinates.h:111
constexpr auto & y()
Definition: coordinates.h:124
constexpr auto xy() const
Definition: coordinates.h:130
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548
constexpr scale omt
Definition: coordinates.h:32
unsigned char get_see_cost() const
Definition: omdata.h:230

References oter_t::get_see_cost(), global_omt_location(), line(), line_to(), coords::omt, overmap_buffer, coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::ter(), coords::coord_point< Point, Origin, Scale >::x(), coords::coord_point< Point, Origin, Scale >::xy(), and coords::coord_point< Point, Origin, Scale >::y().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), and overmap_ui::draw_overmap_chunk().

◆ overmap_sight_range()

int Character::overmap_sight_range ( int  light_level) const

Returns the distance the player can see on the overmap.

Definition at line 658 of file character.cpp.

659{
660 int sight = sight_range( light_level );
661 if( sight < SEEX ) {
662 return 0;
663 }
664 if( sight <= SEEX * 4 ) {
665 return ( sight / ( SEEX / 2 ) );
666 }
667
668 sight = 6;
669 // The higher your perception, the farther you can see.
670 sight += static_cast<int>( get_per() / 2 );
671 // The higher up you are, the farther you can see.
672 sight += std::max( 0, posz() ) * 2;
673 // Mutations like Scout and Topographagnosia affect how far you can see.
674 sight += mutation_value( "overmap_sight" );
675
676 float multiplier = mutation_value( "overmap_multiplier" );
677 // Binoculars double your sight range.
678 const bool has_optic = ( has_item_with_flag( "ZOOM" ) || has_bionic( bio_eye_optic ) ||
679 ( is_mounted() &&
680 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) );
681 if( has_optic ) {
682 multiplier += 1;
683 }
684
685 sight = std::round( sight * multiplier );
686 return std::max( sight, 3 );
687}
static const bionic_id bio_eye_optic("bio_eye_optic")
int sight_range(int light_level) const override
Returns the player's sight range.
Definition: character.cpp:606
static constexpr int SEEX
@ MF_MECH_RECON_VISION
Definition: mtype.h:118

References bio_eye_optic, get_per(), has_bionic(), has_item_with_flag(), is_mounted(), MF_MECH_RECON_VISION, mounted_creature, mutation_value(), posz(), SEEX, and sight_range().

Referenced by overmap_ui::draw_ascii(), overmap_ui::draw_om_sidebar(), overmap_ui::draw_overmap_chunk(), and game::update_overmap_seen().

◆ passive_absorb_hit()

void Character::passive_absorb_hit ( const bodypart_id bp,
damage_unit du 
) const

Check for relevant passive, non-clothing that can absorb damage, and reduce by specified damage unit.

Only flat bonuses are checked here. Multiplicative ones are checked in player::absorb_hit. The damage amount will never be reduced to less than 0. This is called from player::absorb_hit

Definition at line 7921 of file character.cpp.

7922{
7923 // >0 check because some mutations provide negative armor
7924 // Thin skin check goes before subdermal armor plates because SUBdermal
7925 if( du.amount > 0.0f ) {
7926 // HACK: Get rid of this as soon as CUT and STAB are split
7927 if( du.type == DT_STAB ) {
7928 damage_unit du_copy = du;
7929 du_copy.type = DT_CUT;
7930 du.amount -= mutation_armor( bp, du_copy );
7931 } else {
7932 du.amount -= mutation_armor( bp, du );
7933 }
7934 }
7935 du.amount -= bionic_armor_bonus( bp, du.type ); //Check for passive armor bionics
7936 du.amount -= mabuff_armor_bonus( du.type );
7937 du.amount = std::max( 0.0f, du.amount );
7938}
int mabuff_armor_bonus(damage_type type) const
Returns the armor bonus against given type from martial arts buffs.
float bionic_armor_bonus(const bodypart_id &bp, damage_type dt) const
Check for passive bionics that provide armor, and returns the armor bonus This is called from player:...
Definition: character.cpp:8228

References damage_unit::amount, bionic_armor_bonus(), DT_CUT, DT_STAB, mabuff_armor_bonus(), mutation_armor(), and damage_unit::type.

Referenced by absorb_hit(), and character_funcs::is_bp_immune_to().

◆ passive_power_gen()

void Character::passive_power_gen ( bionic bio)

Passively produce power from PERPETUAL fuel.

Definition at line 1355 of file bionics.cpp.

1356{
1357 const float passive_fuel_efficiency = bio.info().passive_fuel_efficiency;
1358 if( bio.info().fuel_opts.empty() || bio.is_this_fuel_powered( fuel_type_muscle ) ||
1359 passive_fuel_efficiency == 0.0 ) {
1360 return;
1361 }
1362 const float effective_passive_efficiency = get_effective_efficiency( bio, passive_fuel_efficiency );
1363 const std::vector<itype_id> &fuel_available = get_fuel_available( bio.id );
1364 map &here = get_map();
1365
1366 for( const itype_id &fuel : fuel_available ) {
1367 const item &tmp_fuel = item( fuel );
1368 const int fuel_energy = tmp_fuel.fuel_energy();
1369 if( !tmp_fuel.has_flag( flag_PERPETUAL ) ) {
1370 continue;
1371 }
1372
1373 if( fuel == fuel_type_sun_light ) {
1374 const double modifier = g->natural_light_level( pos().z ) / default_daylight_level();
1375 mod_power_level( units::from_kilojoule( fuel_energy ) * modifier * effective_passive_efficiency );
1376 } else if( fuel == fuel_type_wind ) {
1377 int vehwindspeed = 0;
1378 const optional_vpart_position vp = here.veh_at( pos() );
1379 if( vp ) {
1380 // vehicle velocity in mph
1381 vehwindspeed = std::abs( vp->vehicle().velocity / 100 );
1382 }
1384 const double windpower = get_local_windpower( weather.windspeed + vehwindspeed,
1385 overmap_buffer.ter( global_omt_location() ), pos(), weather.winddirection,
1386 g->is_sheltered( pos() ) );
1387 mod_power_level( units::from_kilojoule( fuel_energy ) * windpower * effective_passive_efficiency );
1388 } else {
1389 mod_power_level( units::from_kilojoule( fuel_energy ) * effective_passive_efficiency );
1390 }
1391
1392 heat_emission( bio, fuel_energy );
1393 if( bio.info().power_gen_emission ) {
1394 here.emit_field( pos(), bio.info().power_gen_emission );
1395 }
1396 }
1397}
float passive_fuel_efficiency
Fraction of fuel energy passively converted to bionic power.
Definition: bionics.h:75

References default_daylight_level(), flag_PERPETUAL(), units::from_kilojoule(), item::fuel_energy(), bionic_data::fuel_opts, fuel_type_muscle, fuel_type_sun_light, fuel_type_wind, g, get_effective_efficiency(), get_fuel_available(), get_local_windpower(), get_map(), get_weather(), global_omt_location(), item::has_flag(), heat_emission(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), bionic::id, bionic::info(), bionic::is_this_fuel_powered(), mod_power_level(), overmap_buffer, bionic_data::passive_fuel_efficiency, pos(), bionic_data::power_gen_emission, and overmapbuffer::ter().

Referenced by process_bionic().

◆ perform_install()

void Character::perform_install ( bionic_id  bid,
bionic_id  upbid,
int  difficulty,
int  success,
int  pl_skill,
const std::string &  installer_name,
const std::vector< trait_id > &  trait_to_rem 
)

Success or failure of installation happens here.

Definition at line 2371 of file bionics.cpp.

2374{
2375
2376 g->events().send<event_type::installs_cbm>( getID(), bid );
2377 if( upbid != bionic_id( "" ) ) {
2378 remove_bionic( upbid );
2379 //~ %1$s - name of the bionic to be upgraded (inferior), %2$s - name of the upgraded bionic (superior).
2380 add_msg( m_good, _( "Upgraded %1$s to %2$s." ),
2381 upbid.obj().name, bid.obj().name );
2382 } else {
2383 //~ %s - name of the bionic.
2384 add_msg( m_good, _( "Installed %s." ), bid.obj().name );
2385 }
2386
2387 add_bionic( bid );
2388
2389 if( !trait_to_rem.empty() ) {
2390 for( const trait_id &tid : trait_to_rem ) {
2391 if( has_trait( tid ) ) {
2392 remove_mutation( tid );
2393 }
2394 }
2395 }
2396 if( success <= 0 ) {
2397 g->events().send<event_type::fails_to_install_cbm>( getID(), bid );
2398
2399 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2400 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2401 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2402 ( 10.0 ) );
2403 bionics_install_failure( installer_name, difficulty, success, adjusted_skill );
2404 }
2405 get_map().invalidate_map_cache( g->get_levz() );
2406}
void remove_bionic(const bionic_id &b)
Removes a bionic from my_bionics[].
Definition: bionics.cpp:2634
void bionics_install_failure(const std::string &installer, int difficulty, int success, float adjusted_skill)
Definition: bionics.cpp:2448
void invalidate_map_cache(const int zlev)
Definition: map.cpp:8970
@ fails_to_install_cbm

References _, add_bionic(), add_msg(), bionic_id, bionics_install_failure(), fails_to_install_cbm, g, get_map(), getID(), has_trait(), installs_cbm, map::invalidate_map_cache(), m_good, bionic_data::name, string_id< T >::obj(), remove_bionic(), remove_mutation(), and behavior::success.

Referenced by install_bionics(), and activity_handlers::operation_do_turn().

◆ perform_special_attacks()

void Character::perform_special_attacks ( Creature t,
dealt_damage_instance dealt_dam 
)

Performs special attacks and their effects (poisonous, stinger, etc.)

Definition at line 1848 of file melee.cpp.

1849{
1850 std::vector<special_attack> special_attacks = mutation_attacks( t );
1851
1852 bool practiced = false;
1853 for( const auto &att : special_attacks ) {
1854 if( t.is_dead_state() ) {
1855 break;
1856 }
1857
1858 // TODO: Make this hit roll use unarmed skill, not weapon skill + weapon to_hit
1859 int hit_spread = t.deal_melee_attack( this, hit_roll() * 0.8 );
1860 if( hit_spread >= 0 ) {
1861 t.deal_melee_hit( this, hit_spread, false, att.damage, dealt_dam );
1862 if( !practiced ) {
1863 // Practice unarmed, at most once per combo
1864 practiced = true;
1865 as_player()->practice( skill_unarmed, rng( 0, 10 ) );
1866 }
1867 }
1868 int dam = dealt_dam.total_damage();
1869 if( dam > 0 ) {
1870 player_hit_message( this, att.text, t, dam );
1871 }
1872 }
1873}
std::vector< special_attack > mutation_attacks(Creature &t) const
Returns a vector of valid mutation attacks.
Definition: melee.cpp:2020

References Creature::as_player(), Creature::deal_melee_attack(), Creature::deal_melee_hit(), hit_roll(), Creature::is_dead_state(), mutation_attacks(), player_hit_message(), practice(), rng(), skill_unarmed, and dealt_damage_instance::total_damage().

Referenced by melee_attack().

◆ perform_technique()

void Character::perform_technique ( const ma_technique technique,
Creature t,
damage_instance di,
int &  move_cost 
)
Intelligence slightly increases chance to learn techniques when using CQB bionic

Definition at line 1426 of file melee.cpp.

1428{
1429 add_msg( m_debug, "dmg before tec:" );
1430 print_damage_info( di );
1431
1432 for( damage_unit &du : di.damage_units ) {
1433 // TODO: Allow techniques to add more damage types to attacks
1434 if( du.amount <= 0 ) {
1435 continue;
1436 }
1437
1438 du.amount += technique.damage_bonus( *this, du.type );
1439 du.damage_multiplier *= technique.damage_multiplier( *this, du.type );
1440 du.res_pen += technique.armor_penetration( *this, du.type );
1441 }
1442
1443 add_msg( m_debug, "dmg after tec:" );
1444 print_damage_info( di );
1445
1446 move_cost *= technique.move_cost_multiplier( *this );
1447 move_cost += technique.move_cost_penalty( *this );
1448
1449 if( technique.down_dur > 0 ) {
1450 t.add_effect( effect_downed, rng( 1_turns, time_duration::from_turns( technique.down_dur ) ) );
1452 if( bash.amount > 0 ) {
1453 bash.amount += 3;
1454 }
1455 }
1456
1457 if( technique.side_switch ) {
1458 const tripoint b = t.pos();
1459 int newx;
1460 int newy;
1461
1462 if( b.x > posx() ) {
1463 newx = posx() - 1;
1464 } else if( b.x < posx() ) {
1465 newx = posx() + 1;
1466 } else {
1467 newx = b.x;
1468 }
1469
1470 if( b.y > posy() ) {
1471 newy = posy() - 1;
1472 } else if( b.y < posy() ) {
1473 newy = posy() + 1;
1474 } else {
1475 newy = b.y;
1476 }
1477
1478 const tripoint &dest = tripoint( newx, newy, b.z );
1479 if( g->is_empty( dest ) ) {
1480 t.setpos( dest );
1481 }
1482 }
1483
1484 if( technique.stun_dur > 0 && !technique.powerful_knockback ) {
1485 t.add_effect( effect_stunned, rng( 1_turns, time_duration::from_turns( technique.stun_dur ) ) );
1486 }
1487
1488 if( technique.knockback_dist ) {
1489 const tripoint prev_pos = t.pos(); // track target startpoint for knockback_follow
1490 const int kb_offset_x = rng( -technique.knockback_spread, technique.knockback_spread );
1491 const int kb_offset_y = rng( -technique.knockback_spread, technique.knockback_spread );
1492 tripoint kb_point( posx() + kb_offset_x, posy() + kb_offset_y, posz() );
1493 for( int dist = rng( 1, technique.knockback_dist ); dist > 0; dist-- ) {
1494 t.knock_back_from( kb_point );
1495 }
1496 // This technique makes the player follow into the tile the target was knocked from
1497 if( technique.knockback_follow ) {
1498 const optional_vpart_position vp0 = g->m.veh_at( pos() );
1499 vehicle *const veh0 = veh_pointer_or_null( vp0 );
1500 bool to_swimmable = g->m.has_flag( "SWIMMABLE", prev_pos );
1501 bool to_deepwater = g->m.has_flag( TFLAG_DEEP_WATER, prev_pos );
1502
1503 // Check if it's possible to move to the new tile
1504 bool move_issue =
1505 g->is_dangerous_tile( prev_pos ) || // Tile contains fire, etc
1506 ( to_swimmable && to_deepwater ) || // Dive into deep water
1507 is_mounted() ||
1508 ( veh0 != nullptr && std::abs( veh0->velocity ) > 100 ) || // Diving from moving vehicle
1509 ( veh0 != nullptr && veh0->player_in_control( g->u ) ) || // Player is driving
1511
1512 if( !move_issue ) {
1513 if( t.pos() != prev_pos ) {
1514 g->place_player( prev_pos );
1515 g->on_move_effects();
1516 }
1517 }
1518 }
1519 }
1520
1521 player *p = dynamic_cast<player *>( &t );
1522
1523 if( technique.take_weapon && !has_weapon() && p != nullptr && p->is_armed() ) {
1524 if( p->is_player() ) {
1525 add_msg_if_npc( _( "<npcname> disarms you and takes your weapon!" ) );
1526 } else {
1527 add_msg_player_or_npc( _( "You disarm %s and take their weapon!" ),
1528 _( "<npcname> disarms %s and takes their weapon!" ),
1529 p->name );
1530 }
1531 item it = p->remove_weapon();
1532 wield( it );
1533 }
1534
1535 if( technique.disarms && p != nullptr && p->is_armed() ) {
1536 g->m.add_item_or_charges( p->pos(), p->remove_weapon() );
1537 if( p->is_player() ) {
1538 add_msg_if_npc( _( "<npcname> disarms you!" ) );
1539 } else {
1540 add_msg_player_or_npc( _( "You disarm %s!" ),
1541 _( "<npcname> disarms %s!" ),
1542 p->name );
1543 }
1544 }
1545
1546 //AOE attacks, feel free to skip over this lump
1547 if( !technique.aoe.empty() ) {
1548 // Remember out moves and stamina
1549 // We don't want to consume them for every attack!
1550 const int temp_moves = moves;
1551 const int temp_stamina = get_stamina();
1552
1553 std::vector<Creature *> targets;
1554
1555 valid_aoe_technique( t, technique, targets );
1556
1557 //hit only one valid target (pierce through doesn't spread out)
1558 if( technique.aoe == "impale" ) {
1559 // TODO: what if targets is empty
1560 Creature *const v = random_entry( targets );
1561 targets.clear();
1562 targets.push_back( v );
1563 }
1564
1565 //hit the targets in the lists (all candidates if wide or burst, or just the unlucky sod if deep)
1566 int count_hit = 0;
1567 for( Creature *const c : targets ) {
1568 melee_attack( *c, false );
1569 }
1570
1571 t.add_msg_if_player( m_good, vgettext( "%d enemy hit!", "%d enemies hit!", count_hit ), count_hit );
1572 // Extra attacks are free of charge (otherwise AoE attacks would SUCK)
1573 moves = temp_moves;
1574 set_stamina( temp_stamina );
1575 }
1576
1577 //player has a very small chance, based on their intelligence, to learn a style whilst using the CQB bionic
1578 if( has_active_bionic( bio_cqb ) && !martial_arts_data->knows_selected_style() ) {
1579 /** @EFFECT_INT slightly increases chance to learn techniques when using CQB bionic */
1580 // Enhanced Memory Banks bionic doubles chance to learn martial art
1581 const int bionic_boost = has_active_bionic( bionic_id( bio_memory ) ) ? 2 : 1;
1582 if( one_in( ( 1400 - ( get_int() * 50 ) ) / bionic_boost ) ) {
1583 martial_arts_data->learn_current_style_CQB( is_player() );
1584 }
1585 }
1586}
bool valid_aoe_technique(Creature &t, const ma_technique &technique)
Check if an area-of-effect technique has valid targets.
Definition: melee.cpp:1277
bool has_weapon() const override
virtual void setpos(const tripoint &pos)=0
void knock_back_from(const tripoint &p)
Definition: creature.cpp:1945
int knockback_dist
Definition: martialarts.h:125
std::string aoe
Definition: martialarts.h:128
float armor_penetration(const Character &u, damage_type type) const
float damage_multiplier(const Character &u, damage_type type) const
bool side_switch
Definition: martialarts.h:116
float damage_bonus(const Character &u, damage_type type) const
float move_cost_multiplier(const Character &u) const
float move_cost_penalty(const Character &u) const
bool take_weapon
Definition: martialarts.h:133
bool knockback_follow
Definition: martialarts.h:129
bool powerful_knockback
Definition: martialarts.h:127
float knockback_spread
Definition: martialarts.h:126
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:279
int velocity
Definition: vehicle.h:1650
static const efftype_id effect_downed("downed")
static const bionic_id bio_memory("bio_memory")
static void print_damage_info(const damage_instance &di)
Definition: melee.cpp:1409
static damage_unit & get_damage_unit(std::vector< damage_unit > &di, const damage_type dt)
Definition: melee.cpp:1397
static const efftype_id effect_stunned("stunned")
static const efftype_id effect_amigara("amigara")
float res_pen
Definition: damage.h:38
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), damage_unit::amount, ma_technique::aoe, ma_technique::armor_penetration(), b, spell_effect::bash(), bio_cqb, bio_memory, bionic_id, c, ma_technique::damage_bonus(), damage_unit::damage_multiplier, ma_technique::damage_multiplier(), damage_instance::damage_units, anonymous_namespace{iexamine_elevator.cpp}::elevator::dest(), ma_technique::disarms, ma_technique::down_dur, DT_BASH, effect_amigara, effect_downed, effect_stunned, time_duration::from_turns(), g, get_damage_unit(), get_int(), get_stamina(), has_active_bionic(), Creature::has_effect(), has_weapon(), is_armed(), is_mounted(), Creature::is_player(), player::is_player(), Creature::knock_back_from(), ma_technique::knockback_dist, ma_technique::knockback_follow, ma_technique::knockback_spread, m_debug, m_good, martial_arts_data, melee_attack(), move_cost(), ma_technique::move_cost_multiplier(), ma_technique::move_cost_penalty(), Creature::moves, name, one_in(), vehicle::player_in_control(), Creature::pos(), pos(), posx(), posy(), posz(), ma_technique::powerful_knockback, print_damage_info(), random_entry(), remove_weapon(), damage_unit::res_pen, rng(), set_stamina(), Creature::setpos(), ma_technique::side_switch, ma_technique::stun_dur, ma_technique::take_weapon, TFLAG_DEEP_WATER, damage_unit::type, valid_aoe_technique(), veh_pointer_or_null(), vehicle::velocity, vgettext(), and wield().

Referenced by melee_attack().

◆ perform_uninstall()

void Character::perform_uninstall ( bionic_id  bid,
int  difficulty,
int  success,
const units::energy power_lvl,
int  pl_skill 
)

Succes or failure of removal happens here.

Definition at line 2102 of file bionics.cpp.

2104{
2105 map &here = get_map();
2106 if( success > 0 ) {
2107 g->events().send<event_type::removes_cbm>( getID(), bid );
2108
2109 // until bionics can be flagged as non-removable
2110 add_msg_player_or_npc( m_neutral, _( "Your parts are jiggled back into their familiar places." ),
2111 _( "<npcname>'s parts are jiggled back into their familiar places." ) );
2112 add_msg( m_good, _( "Successfully removed %s." ), bid.obj().name );
2113 remove_bionic( bid );
2114
2115 // remove power bank provided by bionic
2116 mod_max_power_level( -power_lvl );
2117
2119 if( bid->itype().is_valid() && !bid.obj().has_flag( flag_BIONIC_FAULTY ) ) {
2120 cbm = item( bid.c_str() );
2121 cbm.faults.emplace( fault_bionic_nonsterile );
2122 }
2123 here.add_item( pos(), cbm );
2124 } else {
2125 g->events().send<event_type::fails_to_remove_cbm>( getID(), bid );
2126 // for chance_of_success calculation, shift skill down to a float between ~0.4 - 30
2127 float adjusted_skill = static_cast<float>( pl_skill ) - std::min( static_cast<float>( 40 ),
2128 static_cast<float>( pl_skill ) - static_cast<float>( pl_skill ) / static_cast<float>
2129 ( 10.0 ) );
2130 bionics_uninstall_failure( difficulty, success, adjusted_skill );
2131
2132 }
2133 here.invalidate_map_cache( g->get_levz() );
2134}
static const flag_str_id flag_BIONIC_FAULTY("BIONIC_FAULTY")
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_burnt_out_bionic("burnt_out_bionic")
void bionics_uninstall_failure(int difficulty, int success, float adjusted_skill)
When a player fails the surgery.
Definition: bionics.cpp:1789
@ fails_to_remove_cbm

References _, add_msg(), Creature::add_msg_player_or_npc(), bionics_uninstall_failure(), string_id< T >::c_str(), fails_to_remove_cbm, fault_bionic_nonsterile, item::faults, flag_BIONIC_FAULTY, g, get_map(), getID(), bionic_data::has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), string_id< T >::is_valid(), bionic_data::itype(), itype_burnt_out_bionic, m_good, m_neutral, mod_max_power_level(), bionic_data::name, string_id< T >::obj(), pos(), remove_bionic(), removes_cbm, and behavior::success.

Referenced by activity_handlers::operation_do_turn(), and uninstall_bionic().

◆ pick_name()

void Character::pick_name ( bool  bUseDefault = false)

Returns a random name from NAMES_*.

Definition at line 129 of file newcharacter.cpp.

130{
131 if( bUseDefault && !get_option<std::string>( "DEF_CHAR_NAME" ).empty() ) {
132 name = get_option<std::string>( "DEF_CHAR_NAME" );
133 } else {
135 }
136}
std::string generate(bool is_male)
Return a random full name given gender.
Definition: name.cpp:128

References Name::generate(), male, and name.

Referenced by avatar::randomize(), npc::randomize(), and set_description().

◆ pick_technique()

matec_id Character::pick_technique ( Creature t,
const item weap,
bool  crit,
bool  dodge_counter,
bool  block_counter 
)

Returns a random valid technique.

Definition at line 1174 of file melee.cpp.

1176{
1177
1178 const std::vector<matec_id> all = martial_arts_data->get_all_techniques( weap );
1179
1180 std::vector<matec_id> possible;
1181
1182 bool downed = t.has_effect( effect_downed );
1183 bool stunned = t.has_effect( effect_stunned );
1184 bool wall_adjacent = g->m.is_wall_adjacent( pos() );
1185
1186 // first add non-aoe tecs
1187 for( const matec_id &tec_id : all ) {
1188 const ma_technique &tec = tec_id.obj();
1189
1190 // ignore "dummy" techniques like WBLOCK_1
1191 if( tec.dummy ) {
1192 continue;
1193 }
1194
1195 // skip defensive techniques
1196 if( tec.defensive ) {
1197 continue;
1198 }
1199
1200 // skip wall adjacent techniques if not next to a wall
1201 if( tec.wall_adjacent && !wall_adjacent ) {
1202 continue;
1203 }
1204
1205 // skip dodge counter techniques
1206 if( dodge_counter != tec.dodge_counter ) {
1207 continue;
1208 }
1209
1210 // skip block counter techniques
1211 if( block_counter != tec.block_counter ) {
1212 continue;
1213 }
1214
1215 // if critical then select only from critical tecs
1216 // but allow the technique if its crit ok
1217 if( !tec.crit_ok && ( crit != tec.crit_tec ) ) {
1218 continue;
1219 }
1220
1221 // don't apply downing techniques to someone who's already downed
1222 if( downed && tec.down_dur > 0 ) {
1223 continue;
1224 }
1225
1226 // don't apply "downed only" techniques to someone who's not downed
1227 if( !downed && tec.downed_target ) {
1228 continue;
1229 }
1230
1231 // don't apply "stunned only" techniques to someone who's not stunned
1232 if( !stunned && tec.stunned_target ) {
1233 continue;
1234 }
1235
1236 // don't apply disarming techniques to someone without a weapon
1237 // TODO: these are the stat requirements for tec_disarm
1238 // dice( dex_cur + get_skill_level("unarmed"), 8) >
1239 // dice(p->dex_cur + p->get_skill_level("melee"), 10))
1240 if( tec.disarms && !t.has_weapon() ) {
1241 continue;
1242 }
1243
1244 if( ( tec.take_weapon && ( has_weapon() || !t.has_weapon() ) ) ) {
1245 continue;
1246 }
1247
1248 // Don't apply humanoid-only techniques to non-humanoids
1249 if( tec.human_target && !t.in_species( HUMAN ) ) {
1250 continue;
1251 }
1252 // if aoe, check if there are valid targets
1253 if( !tec.aoe.empty() && !valid_aoe_technique( t, tec ) ) {
1254 continue;
1255 }
1256
1257 // If we have negative weighting then roll to see if it's valid this time
1258 if( tec.weighting < 0 && !one_in( std::abs( tec.weighting ) ) ) {
1259 continue;
1260 }
1261
1262 if( tec.is_valid_character( *this ) ) {
1263 possible.push_back( tec.id );
1264
1265 //add weighted options into the list extra times, to increase their chance of being selected
1266 if( tec.weighting > 1 ) {
1267 for( int i = 1; i < tec.weighting; i++ ) {
1268 possible.push_back( tec.id );
1269 }
1270 }
1271 }
1272 }
1273
1274 return random_entry( possible, tec_none );
1275}
virtual bool in_species(const species_id &) const
Definition: creature.cpp:993
bool stunned_target
Definition: martialarts.h:144
bool human_target
Definition: martialarts.h:146
bool block_counter
Definition: martialarts.h:135
bool wall_adjacent
Definition: martialarts.h:145
bool dodge_counter
Definition: martialarts.h:134
bool downed_target
Definition: martialarts.h:143
static const species_id HUMAN("HUMAN")
const std::array< type, 4 > all
For the purposes of iteration.
Definition: om_direction.h:27

References om_direction::all, ma_technique::aoe, ma_technique::block_counter, ma_technique::crit_ok, ma_technique::crit_tec, ma_technique::defensive, ma_technique::disarms, ma_technique::dodge_counter, ma_technique::down_dur, ma_technique::downed_target, ma_technique::dummy, effect_downed, effect_stunned, g, Creature::has_effect(), Creature::has_weapon(), has_weapon(), HUMAN, ma_technique::human_target, ma_technique::id, Creature::in_species(), ma_technique::is_valid_character(), martial_arts_data, one_in(), pos(), random_entry(), ma_technique::stunned_target, ma_technique::take_weapon, tec_none, valid_aoe_technique(), ma_technique::wall_adjacent, and ma_technique::weighting.

Referenced by block_hit(), melee_attack(), and on_dodge().

◆ place_corpse() [1/2]

void Character::place_corpse ( )

Definition at line 10134 of file character.cpp.

10135{
10136 //If the character/NPC is on a distant mission, don't drop their their gear when they die since they still have a local pos
10137 if( !death_drops ) {
10138 return;
10139 }
10140 std::vector<item *> tmp = inv_dump();
10142 map &here = get_map();
10143 for( auto itm : tmp ) {
10144 here.add_item_or_charges( pos(), *itm );
10145 }
10146 for( const bionic &bio : *my_bionics ) {
10147 if( bio.info().itype().is_valid() ) {
10148 item cbm( bio.id.str(), calendar::turn );
10149 cbm.faults.emplace( fault_bionic_nonsterile );
10150 body.components.push_back( cbm );
10151 }
10152 }
10153
10154 // Restore amount of installed pseudo-modules of Power Storage Units
10155 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10156 for( int i = 0; i < storage_modules.first; ++i ) {
10158 cbm.faults.emplace( fault_bionic_nonsterile );
10159 body.components.push_back( cbm );
10160 }
10161 for( int i = 0; i < storage_modules.second; ++i ) {
10163 cbm.faults.emplace( fault_bionic_nonsterile );
10164 body.components.push_back( cbm );
10165 }
10166 here.add_item_or_charges( pos(), body );
10167}
static const itype_id itype_power_storage("bio_power_storage")
static const fault_id fault_bionic_nonsterile("fault_bionic_nonsterile")
static const itype_id itype_power_storage_mkII("bio_power_storage_mkII")
bool death_drops
Definition: character.h:252
std::pair< int, int > amount_of_storage_bionics() const
Returns amount of Storage CBMs in the corpse.
Definition: bionics.cpp:2676
std::map< bodypart_str_id, bodypart > body
this is the actual body of the creature
Definition: creature.h:503
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:512

References amount_of_storage_bionics(), Creature::body, death_drops, fault_bionic_nonsterile, item::faults, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), inv_dump(), itype_power_storage, itype_power_storage_mkII, item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), pos(), and calendar::turn.

Referenced by npc::die(), game::handle_action(), and game::is_game_over().

◆ place_corpse() [2/2]

void Character::place_corpse ( const tripoint_abs_omt om_target)

Definition at line 10169 of file character.cpp.

10170{
10171 tinymap bay;
10172 bay.load( project_to<coords::sm>( om_target ), false );
10173 point fin{ rng( 1, SEEX * 2 - 2 ), rng( 1, SEEX * 2 - 2 ) };
10174 // This makes no sense at all. It may find a random tile without furniture, but
10175 // if the first try to find one fails, it will go through all tiles of the map
10176 // and essentially select the last one that has no furniture.
10177 // Q: Why check for furniture? (Check for passable or can-place-items seems more useful.)
10178 // Q: Why not grep a random point out of all the possible points (e.g. via random_entry)?
10179 // Q: Why use furn_str_id instead of f_null?
10180 // TODO: fix it, see above.
10181 if( bay.furn( fin ) != furn_str_id( "f_null" ) ) {
10182 for( const tripoint &p : bay.points_on_zlevel() ) {
10183 if( bay.furn( p ) == furn_str_id( "f_null" ) ) {
10184 fin.x = p.x;
10185 fin.y = p.y;
10186 }
10187 }
10188 }
10189
10190 std::vector<item *> tmp = inv_dump();
10192 for( auto itm : tmp ) {
10193 bay.add_item_or_charges( fin, *itm );
10194 }
10195 for( const bionic &bio : *my_bionics ) {
10196 if( bio.info().itype().is_valid() ) {
10197 body.put_in( item( bio.info().itype(), calendar::turn ) );
10198 }
10199 }
10200
10201 // Restore amount of installed pseudo-modules of Power Storage Units
10202 std::pair<int, int> storage_modules = amount_of_storage_bionics();
10203 for( int i = 0; i < storage_modules.first; ++i ) {
10204 body.put_in( item( "bio_power_storage" ) );
10205 }
10206 for( int i = 0; i < storage_modules.second; ++i ) {
10207 body.put_in( item( "bio_power_storage_mkII" ) );
10208 }
10209 bay.add_item_or_charges( fin, body );
10210}
tripoint_range< tripoint > points_on_zlevel() const
Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub)...
Definition: map.cpp:8783
furn_id furn(const tripoint &p) const
Definition: map.cpp:1413
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6750
Definition: map.h:2065

References map::add_item_or_charges(), amount_of_storage_bionics(), Creature::body, map::furn(), inv_dump(), map::load(), item::make_corpse(), my_bionics, name, string_id< mtype >::NULL_ID(), map::points_on_zlevel(), rng(), SEEX, and calendar::turn.

◆ pos()

const tripoint & Character::pos ( ) const
overridevirtual

Implements Creature.

Definition at line 601 of file character.cpp.

602{
603 return position;
604}

References position.

Referenced by absorb_hit(), iuse::acidbomb_act(), activate_bionic(), npc::activate_item(), activate_mutation(), enchantment::activate_passive(), activity_on_turn_move_loot(), map::add_field(), add_known_trap(), inventory_selector::add_nearby_items(), npc::address_player(), npc::alt_attack(), map::apparent_light_helper(), map::apply_character_light(), apply_persistent_morale(), iuse::artifact(), npc::assess_danger(), assign_activity(), activity_handlers::atm_do_turn(), Creature::auto_find_hostile_target(), game::autopilot_vehicles(), npc::avoid_friendly_fire(), avoid_trap(), iuse::bell(), best_nearby_lifting_assist(), mattack::bio_op_disarm(), blossoms(), iuse::boltcutters(), map::build_vision_transparency_cache(), burn_fuel(), iuse::burrow(), game::butcher(), activity_handlers::butcher_finish(), butchery_drops_harvest(), butchery_quarter(), set_transformed_iuse::bypass(), iuse::cable_attach(), calc_needs_rates(), calculate_aim_cap(), calculate_dispersion(), iuse::call_of_tindalos(), iuse::camera(), player::can_continue_craft(), can_examine_at(), can_hear(), can_mount(), npc::can_move_to(), character_funcs::can_see_fine_details(), iuse_transform::can_use(), firestarter_actor::can_use(), iuse::capture_monster_act(), iexamine::cardreader_foodplace(), enchantment::cast_enchantment_spell(), iexamine::chainfence(), debug_menu::character_edit_menu(), game::chat(), check_art_charge_req(), player::check_eligible_containers_for_crafting(), vehicle::check_heli_ascend(), check_mount_is_spooked(), check_mount_will_move(), npc::check_or_use_weapon_cbm(), check_outbounds_activity(), relic_funcs::check_recharge_reqs(), iuse::chop_tree(), avatar::clear_memorized_tile(), doors::close_door(), game_menus::inv::compare(), complete_construction(), veh_interact::complete_vehicle(), consider_butchery(), consume_charges(), consume_effects(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), game::control_vehicle(), cough(), npc::could_move_onto(), player::craft_consume_tools(), crafting_inventory(), craft_command::create_in_progress_craft(), game::create_starting_npcs(), map::creature_in_field(), game::critter_at(), iuse::crowbar(), iexamine::curtains(), iuse::cut_log_into_planks(), salvage_actor::cut_up(), deactivate_bionic(), deal_damage(), debug_menu::debug(), defer_move(), item_location::impl::item_on_map::describe(), item_location::impl::item_on_vehicle::describe(), trap::detect_trap(), npc::die(), iuse::dig(), iuse::dig_channel(), iuse::directional_antenna(), crafting::disassemble_all(), character_display::disp_info(), game::disp_NPCs(), game::display_scent(), npc::dispose_item(), npc::do_npc_read(), character_funcs::do_pause(), npc::do_pulp(), avatar::do_read(), npc::do_reload(), game::do_turn(), drop_activity_actor::do_turn(), stash_activity_actor::do_turn(), move_items_activity_actor::do_turn(), pickup_activity_actor::do_turn(), throw_activity_actor::do_turn(), iexamine::door_peephole(), game::draw(), draw_bionics_titlebar(), draw_cone_aoe_curses(), draw_env_compact(), draw_health_classic(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), game::draw_look_around_cursor(), draw_speed_tab(), game::draw_ter(), target_ui::draw_terrain_overlay(), draw_throw_aim(), draw_time_classic(), game::draw_trail_to_square(), draw_veh_compact(), draw_veh_padding(), game::drop(), drop(), drop_invalid_inventory(), npc::drop_items(), talk_function::drop_weapon(), monexamine::dump_items(), eat(), avatar_action::eat_here(), eff_fun_fungus(), eff_fun_hallu(), iuse::einktabletpc(), iexamine::elevator(), emit_radio_signal(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), env_surgery_bonus(), game::examine(), craft_command::execute(), npc::execute_action(), extract_or_wreck_cbms(), npc::faction_display(), iuse::fill_pit(), character_funcs::find_ammo_items_or_mags(), find_auto_consume(), find_best_bench(), npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), npc::find_item(), activity_handlers::find_mount_do_turn(), game::find_nearby_items(), game::find_or_make_stairs(), find_remote_fuel(), character_funcs::fine_detail_vision_mod(), hacking_activity_actor::finish(), npc::finish_read(), fire(), ranged::fire_gun(), iuse::fishing_rod(), game::fling_creature(), floor_bedding_warmth(), floor_item_warmth(), floor_warmth(), iexamine::flower_marloss(), iexamine::flower_poppy(), activity_handlers::forage_finish(), forced_dismount(), fungal_effects::fungalize(), iuse::fungicide(), mattack::fungus_sprout(), iexamine::fvat_full(), activity_handlers::game_do_turn(), iuse::gasmask(), iexamine::gaspump(), iuse::geiger(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), avatar::get_book_reader(), character_funcs::get_crafting_helpers(), game::get_dangerous_tile(), activatable_inventory_preset::get_denial(), get_dodge(), player::get_eligible_containers_for_crafting(), get_heat_radiation(), get_hostile_creatures(), get_item_location(), avatar::get_memorized_tile(), get_next_auto_move_direction(), overmap_ui::get_overmap_path_to(), npc::get_path_avoid(), get_patient(), get_temp(), game::get_veh_dir_indicator_location(), get_visible_creatures(), ranged::get_weapon_dispersion(), talk_function::give_all_aid(), npc::go_to_omt_destination(), npc::good_escape_direction(), grab(), mattack::grab_drag(), game::grabbed_furn_move(), game::grabbed_veh_move(), npc::guard_current_pos(), iuse::gun_repair(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), iuse::hacksaw(), activity_handlers::hacksaw_finish(), iuse::hammer(), handbrake(), game::handle_action(), target_ui::handle_cursor_movement(), handle_harvest(), handle_melee_wear(), item::handle_pickup_ownership(), npc::handle_sound(), vehicle::handle_trap(), hardcoded_effects(), has_alarm_clock(), has_fire(), has_neighbor(), has_watch(), haul(), npc::heal_player(), npc::heal_self(), heat_emission(), iuse::honeycomb(), i_add_or_drop(), i_rem(), i_rem_keep_contents(), impact(), in_climate_control(), npc_trading::init_buying(), iexamine::intercom(), invoke_item(), npc::is_active(), enchantment::is_active(), place_trap_actor::is_allowed(), is_deaf(), is_driving(), monster::is_fleeing(), game::is_game_over(), game::is_in_viewport(), is_snuggling(), is_solid_neighbor(), ma_requirements::is_valid_character(), is_visible_in_range(), iuse::jackhammer(), monexamine::kill_zslave(), knock_back_to(), game::knockback(), knows_trap(), firestarter_actor::light_mod(), game::list_items(), game::list_monsters(), avatar_funcs::list_potential_theft_witnesses(), vehicle_prototype::load(), game::load(), avatar::load_map_memory(), aim_activity_actor::load_RAS_weapon(), activity_handlers::lockpicking_finish(), activity_handlers::longsalvage_finish(), game::look_around(), npc::look_for_player(), loot(), iuse::lumber(), ranged::make_gun_sound_effect(), activity_handlers::make_zlave_finish(), iuse::makemound(), item_action_generator::map_actions_to_items(), marloss_common(), melee_attack(), melee_special_effects(), avatar::memorize_symbol(), avatar::memorize_tile(), npc::method_of_attack(), mill_activate(), target_handler::mode_turrets(), modify_morale(), game::mon_info_update(), game::monmove(), iuse::mop(), npc::move(), avatar_action::move(), npc::move_away_from(), npc::move_to(), npc::move_to_next(), firestarter_actor::moves_cost_by_fuel(), game::moving_vehicle_dismount(), npc::mug_player(), multicooker_hallu(), mutation_effect(), npc::mutiny(), iuse::mycus(), inventory_selector::naturalize_category(), nearby(), iuse::note_bionics(), npc::npc_dismount(), game::npc_menu(), mattack::nurse_assist(), mattack::nurse_check_up(), mattack::nurse_operate(), item_location::impl::item_on_map::obtain_cost(), item_location::impl::item_on_vehicle::obtain_cost(), on_dodge(), npc::on_load(), item::on_pickup(), item::on_takeoff(), item::on_wear(), open(), map::open_door(), activity_handlers::operation_do_turn(), activity_handlers::operation_finish(), operator_present(), game::overmap_npc_move(), iuse::oxytorch(), activity_handlers::oxytorch_do_turn(), activity_handlers::oxytorch_finish(), passive_power_gen(), iexamine::pay_gas(), game::peek(), perform_technique(), perform_uninstall(), perform_zone_activity_turn(), game::phasing_move(), debug_menu::pick_character(), pick_plant(), character_funcs::pick_safe_adjacent_tile(), pick_technique(), npc::pick_up_item(), iuse::pickaxe(), game::pickup_feet(), iexamine::pit_covered(), place_and_add_as_known(), place_corpse(), npc::place_on_map(), game::place_player(), start_location::place_player(), game::place_player_overmap(), iuse::play_music(), vehicle::player_in_control(), map::player_in_field(), player_on_couch(), pldrive(), item_location::impl::item_on_person::position(), firestarter_actor::prep_firestarter_use(), npc::pretend_fire(), print_aim(), npc::print_info(), print_items(), game::process_artifact(), process_bionic(), process_effects_internal(), process_items(), relic_funcs::process_recharge_entry(), sounds::process_sound_markers(), process_turn(), prompt_disassemble_single(), activity_handlers::pry_nails_finish(), iexamine::quern_examine(), plot_options::query_seed(), avatar_action::ramp_move(), mattack::ranged_pull(), reach_attack(), npc::reach_omt_destination(), read(), recalc_speed_bonus(), ranged::recoil_vehicle(), activity_handlers::reload_finish(), vehicle::remote_controlled(), monexamine::remove_bag_from(), render_wind(), veh_utils::repair_part(), requirements_map(), firestarter_actor::resolve_firestarter_use(), iuse::robotcontrol(), iuse::robotcontrol_can_target(), rod_fish(), character_funcs::roll_can_sleep(), rooted(), rooted_message(), route_adjacent(), target_ui::run(), examine_item_menu::run(), run_cost(), avatar::save_map_memory(), npc::say(), character_funcs::search_surroundings(), npc::see_item_say_smth(), sees(), sees_with_infrared(), conditional_t< T >::set_is_driving(), set_item_inventory(), avatar::set_movement_mode(), conditional_t< T >::set_npc_role_nearby(), talk_effect_fun_t::set_u_buy_monster(), monster::setpos(), npc::setpos(), activity_handlers::shear_finish(), npc::shift(), shout(), show_armor_layers_ui(), iexamine::shrub_marloss(), sight_range(), sinkhole_safety_roll(), smash(), smoker_activate(), iexamine::smoker_options(), spawn_animal(), spawn_spores(), activity_handlers::spellcasting_finish(), spores(), standard_npc::standard_npc(), autodrive_activity_actor::start(), activity_handlers::start_fire_do_turn(), game::start_game(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_schizophrenia(), suffer_in_sunlight(), suffer_while_underwater(), game::swap_critters(), avatar_action::swim(), symbol_color(), takeoff(), iuse::talking_doll(), iuse::tazer(), ranged::throw_item(), toolweapon_off(), toolweapon_on(), iuse::tow_attach(), iexamine::trap(), activity_handlers::travel_do_turn(), npc::travel_overmap(), iexamine::tree_hickory(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), explosion_iuse::trigger_explosion(), try_consume(), avatar_funcs::try_disarm_npc(), try_fuel_fire(), game::try_get_left_click_action(), game::try_get_right_click_action(), try_reject_mutagen(), salvage_actor::try_to_cut_up(), avatar_funcs::try_to_sleep(), iuse::unfold_generic(), uninstall_bionic(), avatar_funcs::unload_item(), update_bodytemp(), update_needs(), npc::update_path(), game::update_stair_monsters(), editmap::update_view_with_help(), iuse_transform::use(), countdown_actor::use(), explosion_iuse::use(), unfold_vehicle_iuse::use(), delayed_transform_iuse::use(), set_transform_iuse::use(), set_transformed_iuse::use(), place_monster_iuse::use(), place_npc_iuse::use(), pick_lock_actor::use(), deploy_furn_actor::use(), firestarter_actor::use(), fireweapon_off_actor::use(), fireweapon_on_actor::use(), manualnoise_actor::use(), musical_instrument_actor::use(), holster_actor::use(), heal_actor::use(), place_trap_actor::use(), emit_actor::use(), mutagen_iv_actor::use(), deploy_tent_actor::use(), unpack_actor::use(), use_charges(), use_fire(), valid_aoe_technique(), game::validate_camps(), game::vertical_move(), activity_handlers::vibe_do_turn(), vomit(), iuse::vortex(), wait(), game::walk_move(), npc::warn_about(), iuse::weather_tool(), npc::wield(), avatar_action::wield(), npc::wield_better_weapon(), npc::wont_hit_friend(), npc::worker_downtime(), and game::zones_manager().

◆ position_to_wear_new_item()

std::list< item >::iterator Character::position_to_wear_new_item ( const item new_item)
protected

Return the position in the worn list where new_item would be put by default.

Definition at line 3954 of file character.cpp.

3955{
3956 // By default we put this item on after the last item on the same or any
3957 // lower layer.
3958 return std::find_if(
3959 worn.rbegin(), worn.rend(),
3960 [&]( const item & w ) {
3961 return w.get_layer() <= new_item.get_layer();
3962 }
3963 ).base();
3964}

References worn.

Referenced by item_encumb(), and wear_item().

◆ posx()

◆ posy()

◆ posz()

int Character::posz ( ) const
inlineoverridevirtual

◆ pour_into() [1/2]

bool Character::pour_into ( item container,
item liquid 
)

Try to pour the given liquid into the given container/vehicle.

The transferred charges are removed from the liquid item. Check the charges of afterwards to see if anything has been transferred at all. The functions do not consume any move points.

Returns
Whether anything has been moved at all. false indicates the transfer is not possible at all. true indicates at least some of the liquid has been moved.

Definition at line 6383 of file character.cpp.

6384{
6385 std::string err;
6386 const int amount = container.get_remaining_capacity_for_liquid( liquid, *this, &err );
6387
6388 if( !err.empty() ) {
6389 add_msg_if_player( m_bad, err );
6390 return false;
6391 }
6392
6393 add_msg_if_player( _( "You pour %1$s into the %2$s." ), liquid.tname(), container.tname() );
6394
6395 container.fill_with( liquid, amount );
6396 inv.unsort();
6397
6398 if( liquid.charges > 0 ) {
6399 add_msg_if_player( _( "There's some left over!" ) );
6400 }
6401
6402 return true;
6403}
void fill_with(item &liquid, int amount=INFINITE_CHARGES)
Fill item with liquid up to its capacity.
Definition: item.cpp:8569
int get_remaining_capacity_for_liquid(const item &liquid, bool allow_bucket=false, std::string *err=nullptr) const
How much more of this liquid (in charges) can be put in this container.
Definition: item.cpp:8431

References _, Creature::add_msg_if_player(), item::charges, item::fill_with(), item::get_remaining_capacity_for_liquid(), inv, m_bad, item::tname(), and inventory::unsort().

Referenced by activity_handlers::fill_liquid_do_turn().

◆ pour_into() [2/2]

bool Character::pour_into ( vehicle veh,
item liquid 
)

Definition at line 6405 of file character.cpp.

6406{
6407 auto sel = [&]( const vehicle_part & pt ) {
6408 return pt.is_tank() && pt.can_reload( liquid );
6409 };
6410
6411 auto stack = units::legacy_volume_factor / liquid.type->stack_size;
6412 auto title = string_format( _( "Select target tank for <color_%s>%.1fL %s</color>" ),
6413 get_all_colors().get_name( liquid.color() ),
6414 round_up( to_liter( liquid.charges * stack ), 1 ),
6415 liquid.tname() );
6416
6417 auto &tank = veh_interact::select_part( veh, sel, title );
6418 if( !tank ) {
6419 return false;
6420 }
6421
6422 tank.fill_with( liquid );
6423
6424 //~ $1 - vehicle name, $2 - part name, $3 - liquid type
6425 add_msg_if_player( _( "You refill the %1$s's %2$s with %3$s." ),
6426 veh.name, tank.name(), liquid.type_name() );
6427
6428 if( liquid.charges > 0 ) {
6429 add_msg_if_player( _( "There's some left over!" ) );
6430 }
6431 return true;
6432}
double round_up(double val, unsigned int dp)
Round a value up at a given decimal place.
nc_color color() const
Returns the default color of the item (e.g.
Definition: item.cpp:4937
static vehicle_part & select_part(const vehicle &veh, const part_selector &sel, const std::string &title=std::string())
Prompt for a part matching the selector function.
std::string name
Definition: vehicle.h:1581
color_manager & get_all_colors()
Definition: color.cpp:45
std::string title(holiday current_holiday)
Definition: path_info.cpp:330
constexpr double to_liter(const volume &v)
Definition: units_volume.h:43
static constexpr volume legacy_volume_factor
Definition: units_volume.h:50
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle_part.h:24

References _, Creature::add_msg_if_player(), item::charges, item::color(), get_all_colors(), get_name(), units::legacy_volume_factor, vehicle::name, round_up(), veh_interact::select_part(), itype::stack_size, string_format(), PATH_INFO::title(), item::tname(), units::to_liter(), item::type, and item::type_name().

◆ power_rating()

float Character::power_rating ( ) const
overridevirtual

Returns an approximation of the creature's strength.

Implements Creature.

Definition at line 9980 of file character.cpp.

9981{
9982 const item &weapon = primary_weapon();
9983 int dmg = std::max( { weapon.damage_melee( DT_BASH ),
9984 weapon.damage_melee( DT_CUT ),
9985 weapon.damage_melee( DT_STAB )
9986 } );
9987
9988 int ret = 2;
9989 // Small guns can be easily hidden from view
9990 if( weapon.volume() <= 250_ml ) {
9991 ret = 2;
9992 } else if( weapon.is_gun() ) {
9993 ret = 4;
9994 } else if( dmg > 12 ) {
9995 ret = 3; // Melee weapon or weapon-y tool
9996 }
9997 if( get_size() == MS_HUGE ) {
9998 ret += 1;
9999 }
10000 if( is_wearing_power_armor( nullptr ) ) {
10001 ret = 5; // No mercy!
10002 }
10003 return ret;
10004}

References item::damage_melee(), DT_BASH, DT_CUT, DT_STAB, get_size(), item::is_gun(), is_wearing_power_armor(), MS_HUGE, primary_weapon(), cata::hash64_detail::ret, and item::volume().

◆ practice()

void Character::practice ( const skill_id id,
int  amount,
int  cap = 99,
bool  suppress_warning = false 
)

This handles giving xp for a skill.

Definition at line 3416 of file character.cpp.

3417{
3418 SkillLevel &level = get_skill_level_object( id );
3419 const Skill &skill = id.obj();
3420 std::string skill_name = skill.name();
3421
3422 if( !level.can_train() && !in_sleep_state() ) {
3423 // If leveling is disabled, don't train, don't drain focus, don't print anything
3424 // Leaving as a skill method rather than global for possible future skill cap setting
3425 return;
3426 }
3427
3428 const auto highest_skill = [&]() {
3429 std::pair<skill_id, int> result( skill_id::NULL_ID(), -1 );
3430 for( const auto &pair : *_skills ) {
3431 const SkillLevel &lobj = pair.second;
3432 if( lobj.level() > result.second ) {
3433 result = std::make_pair( pair.first, lobj.level() );
3434 }
3435 }
3436 return result.first;
3437 };
3438
3439 const bool isSavant = has_trait( trait_SAVANT );
3440 const skill_id savantSkill = isSavant ? highest_skill() : skill_id::NULL_ID();
3441
3442 amount = adjust_for_focus( amount );
3443
3444 if( has_trait( trait_PACIFIST ) && skill.is_combat_skill() ) {
3445 if( !one_in( 3 ) ) {
3446 amount = 0;
3447 }
3448 }
3449 if( has_trait_flag( "PRED2" ) && skill.is_combat_skill() ) {
3450 if( one_in( 3 ) ) {
3451 amount *= 2;
3452 }
3453 }
3454 if( has_trait_flag( "PRED3" ) && skill.is_combat_skill() ) {
3455 amount *= 2;
3456 }
3457
3458 if( has_trait_flag( "PRED4" ) && skill.is_combat_skill() ) {
3459 amount *= 3;
3460 }
3461
3462 if( isSavant && id != savantSkill ) {
3463 amount /= 2;
3464 }
3465
3466 if( amount > 0 && get_skill_level( id ) > cap ) { //blunt grinding cap implementation for crafting
3467 amount = 0;
3468 if( !suppress_warning && one_in( 5 ) ) {
3470 }
3471 }
3472 if( amount > 0 && level.isTraining() ) {
3473 int oldLevel = get_skill_level( id );
3474 get_skill_level_object( id ).train( amount );
3475 int newLevel = get_skill_level( id );
3476 if( newLevel > oldLevel ) {
3477 g->events().send<event_type::gains_skill_level>( getID(), id, newLevel );
3478 }
3479 if( is_player() && newLevel > oldLevel ) {
3480 add_msg( m_good, _( "Your skill in %s has increased to %d!" ), skill_name, newLevel );
3481 }
3482 if( is_player() && newLevel > cap ) {
3483 //inform player immediately that the current recipe can't be used to train further
3484 add_msg( m_info, _( "You feel that %s tasks of this level are becoming trivial." ),
3485 skill_name );
3486 }
3487
3488 int chance_to_drop = focus_pool;
3489 focus_pool -= chance_to_drop / 100;
3490 // Apex Predators don't think about much other than killing.
3491 // They don't lose Focus when practicing combat skills.
3492 if( ( rng( 1, 100 ) <= ( chance_to_drop % 100 ) ) && ( !( has_trait_flag( "PRED4" ) &&
3493 skill.is_combat_skill() ) ) ) {
3494 focus_pool--;
3495 }
3496 }
3497
3499}
static const trait_id trait_SAVANT("SAVANT")
static const trait_id trait_PACIFIST("PACIFIST")
SkillLevel & get_skill_level_object(const skill_id &ident)
Definition: character.cpp:3345
int adjust_for_focus(int amount) const
Definition: character.cpp:9943
bool can_train() const
Definition: skill.cpp:311
bool isTraining() const
Definition: skill.h:117
void practice()
Definition: skill.cpp:297
void train(int amount, bool skip_scaling=false)
Definition: skill.cpp:223
void show_skill_capped_notice(const Character &who, const skill_id &id)
This shows warning to the player that their current activity will not give them xp.

References _, _skills, add_msg(), adjust_for_focus(), SkillLevel::can_train(), focus_pool, g, gains_skill_level, get_skill_level(), get_skill_level_object(), getID(), has_trait(), has_trait_flag(), id, in_sleep_state(), Skill::is_combat_skill(), Creature::is_player(), SkillLevel::isTraining(), SkillLevel::level(), m_good, m_info, Skill::name(), string_id< Skill >::NULL_ID(), one_in(), SkillLevel::practice(), rng(), character_funcs::show_skill_capped_notice(), SkillLevel::train(), trait_PACIFIST, and trait_SAVANT.

Referenced by vehicle::act_on_map(), activity_handlers::butcher_finish(), butchery_drops_harvest(), talk_function::companion_skill_trainer(), crafting::complete_disassemble(), veh_interact::complete_vehicle(), player::craft_skill_gain(), salvage_actor::cut_up(), character_funcs::do_pause(), iuse::einktabletpc(), heal_actor::finish_using(), ranged::fire_gun(), activity_handlers::fish_do_turn(), iuse::fish_trap(), iexamine::fvat_full(), iuse::gun_repair(), hack_attempt(), computer_session::hack_attempt(), hackveh(), install_bionics(), place_trap_actor::data::load(), activity_handlers::make_zlave_finish(), melee_train(), iuse::multicooker(), on_dodge(), perform_special_attacks(), pick_plant(), vehicle::pldrive(), iexamine::practice_survival_while_foraging(), activity_handlers::pry_nails_finish(), activity_handlers::pulp_do_turn(), repair_item_actor::repair(), veh_utils::repair_part(), activity_handlers::robot_control_finish(), talk_trial::roll(), smash(), activity_handlers::start_fire_finish(), activity_handlers::study_spell_finish(), avatar_action::swim(), ranged::throw_item(), place_trap_actor::use(), and sew_advanced_actor::use().

◆ primary_weapon() [1/2]

item & Character::primary_weapon ( )

Legacy code hack, don't use.

Returns the first wielded weapon or a null item. Use wielded_items instead.

Definition at line 167 of file melee.cpp.

168{
169 return const_cast<item &>( const_cast<const Character *>( this )->primary_weapon() );
170}

References primary_weapon().

Referenced by activate_bionic(), npc::aim(), allocated_invlets(), npc::alt_attack(), apply_damage(), avatar_action::autoattack(), npc::average_damage_dealt(), best_shield(), mattack::bio_op_disarm(), mattack::bio_op_takedown(), block_hit(), npc::can_reload_current(), can_wear(), can_wield(), cast_spell(), npc::character_danger(), check_art_charge_req(), npc::check_or_use_weapon_cbm(), consume(), mattack::copbot(), crafting_inventory(), deactivate_bionic(), deal_damage(), npc::decide_needs(), dismount(), throw_activity_actor::do_turn(), iuse::ehandcuffs(), explosion_handler::emp_blast(), npc::execute_action(), extended_description(), npc::faction_display(), fire(), ranged::fire_gun(), avatar_action::fire_wielded_weapon(), character_funcs::fmt_wielded_weapon(), forced_dismount(), npc::form_opinion(), mattack::frag(), get_item_position(), get_overlay_ids(), aim_activity_actor::get_weapon(), get_weight(), give_item_to(), mattack::grab(), game::handle_action(), handle_problematic_pickup(), hardcoded_effects(), hardcoded_mutation_attack(), i_at(), i_rem(), npc_trading::init_buying(), character_effects::intimidation(), inv_dump(), npc::invalidate_range_cache(), is_armed(), steal_inventory_preset::is_shown(), ma_requirements::is_valid_character(), is_wielding(), item_handling_cost(), mdeath::jabberwock(), ma_style_callback::key(), game::list_monsters(), load(), character_martial_arts::martialart_use_message(), melee_attack(), melee_special_effects(), avatar_action::mend(), npc::method_of_attack(), npc::move(), avatar_action::move(), npc::move_pause(), npc::move_to(), npc::npc_dismount(), on_dodge(), parse_tags(), monexamine::pet_menu(), pick_one_up(), avatar_action::plthrow(), power_rating(), primary_weapon(), print_aim(), npc::print_info(), game::process_artifact(), item::process_extinguish(), process_items(), mattack::pull_metal_weapon(), activity_handlers::pulp_do_turn(), reach_attack(), reach_attack(), remove_weapon(), mattack::rifle(), mattack::riotbot(), examine_item_menu::run(), character_martial_arts::selected_style_name(), conditional_t< T >::set_can_stow_weapon(), gun_actor::shoot(), short_description_parts(), smash(), npc::smash_ability(), starting_inv(), npc::starting_weapon(), store(), npc::stow_item(), suffer_from_bad_bionics(), suffer_from_schizophrenia(), suffer_from_sunburn(), mattack::tankgun(), avatar_funcs::try_disarm_npc(), game::try_get_right_click_action(), character_funcs::try_wield_contents(), unwield(), update_bodytemp(), trading_window::update_win(), use_amount(), used_weapon(), npc::value(), wear_possessed(), weight_carried_reduced_by(), weather_effect::wet_player(), npc::wield(), avatar::wield(), npc::wield_better_weapon(), npc_ai::wielded_value(), and memorial_logger::write().

◆ primary_weapon() [2/2]

const item & Character::primary_weapon ( ) const

Definition at line 150 of file melee.cpp.

151{
152 if( get_body().find( body_part_arm_r ) == get_body().end() ) {
153 debugmsg( "primary_weapon called before set_anatomy" );
154 return null_item_reference();
155 }
156
157 // TODO: Remove unconst hacks
158 const std::shared_ptr<item> &wielded_const = get_part( body_part_arm_r ).wielding.wielded;
159 std::shared_ptr<item> &wielded = const_cast<std::shared_ptr<item> &>( wielded_const );
160 if( wielded == nullptr ) {
161 wielded = std::make_shared<item>();
162 }
163
164 return *wielded;
165}
const bodypart_str_id body_part_arm_r("arm_r")
wield_status wielding
Definition: bodypart.h:181
std::shared_ptr< item > wielded
Definition: bodypart.h:163

References body_part_arm_r, debugmsg, detail::find(), Creature::get_body(), Creature::get_part(), null_item_reference(), wield_status::wielded, and bodypart::wielding.

◆ print_health()

void Character::print_health ( ) const

Definition at line 4220 of file character.cpp.

4221{
4222 if( !is_player() ) {
4223 return;
4224 }
4225 int current_health = get_healthy();
4226 if( has_trait( trait_SELFAWARE ) ) {
4227 add_msg_if_player( _( "Your current health value is %d." ), current_health );
4228 }
4229
4230 static const std::map<int, std::string> msg_categories = {
4231 { -100, "health_horrible" },
4232 { -50, "health_very_bad" },
4233 { -10, "health_bad" },
4234 { 10, "" },
4235 { 50, "health_good" },
4236 { 100, "health_very_good" },
4237 { INT_MAX, "health_great" }
4238 };
4239
4240 auto iter = msg_categories.lower_bound( current_health );
4241 if( iter != msg_categories.end() && !iter->second.empty() ) {
4242 const translation msg = SNIPPET.random_from_category( iter->second ).value_or( translation() );
4243 add_msg_if_player( current_health > 0 ? m_good : m_bad, "%s", msg );
4244 }
4245}

References _, Creature::add_msg_if_player(), get_healthy(), has_trait(), Creature::is_player(), m_bad, m_good, snippet_library::random_from_category(), SNIPPET, and trait_SELFAWARE.

Referenced by activate_mutation(), and avatar::wake_up().

◆ print_info()

int Character::print_info ( const catacurses::window w,
int  vStart,
int  vLines,
int  column 
) const
overridevirtual

Write information about this creature.

Parameters
wthe window to print the text into.
vStartvertical start to print, that means the first line to print.
vLinesnumber of lines to print at most (printing less is fine).
columnhorizontal start to print (column), horizontal end is one character before the right border of the window (to keep the border).
Returns
The line just behind the last printed line, that means multiple calls to this can be stacked, the return value is acceptable as vStart for the next call without creating empty lines or overwriting lines.

Implements Creature.

Reimplemented in npc.

Definition at line 10359 of file character.cpp.

10360{
10361 mvwprintw( w, point( column, vStart++ ), _( "You (%s)" ), name );
10362 return vStart;
10363}
void mvwprintw(const window &win, point p, const std::string &text)

References _, catacurses::mvwprintw(), and name.

◆ process_bionic()

void Character::process_bionic ( bionic bio)

Handles bionic effects over time of the entered bionic.

Definition at line 1567 of file bionics.cpp.

1568{
1569 if( ( !bio.id->fuel_opts.empty() || bio.id->is_remote_fueled ) && bio.is_auto_start_on() ) {
1570 const float start_threshold = bio.get_auto_start_thresh();
1571 std::vector<itype_id> fuel_available = get_fuel_available( bio.id );
1572 if( bio.id->is_remote_fueled ) {
1573 const itype_id rem_fuel = find_remote_fuel();
1574 const std::string rem_amount = get_value( "rem_" + rem_fuel.str() );
1575 int rem_fuel_stock = 0;
1576 if( !rem_amount.empty() ) {
1577 rem_fuel_stock = std::stoi( rem_amount );
1578 }
1579 if( !rem_fuel.is_empty() && ( rem_fuel_stock > 0 ||
1580 item( rem_fuel ).has_flag( flag_PERPETUAL ) ) ) {
1581 fuel_available.emplace_back( rem_fuel );
1582 }
1583 }
1584 if( !fuel_available.empty() && get_power_level() <= start_threshold * get_max_power_level() ) {
1585 g->u.activate_bionic( bio );
1586 } else if( get_power_level() <= start_threshold * get_max_power_level() &&
1587 calendar::once_every( 1_hours ) ) {
1588 add_msg_player_or_npc( m_bad, _( "Your %s does not have enough fuel to use Auto Start." ),
1589 _( "<npcname>'s %s does not have enough fuel to use Auto Start." ),
1590 bio.info().name );
1591 }
1592 }
1593
1594 // Only powered bionics should be processed
1595 if( !bio.powered ) {
1596 passive_power_gen( bio );
1597 return;
1598 }
1599
1600 // These might be affected by environmental conditions, status effects, faulty bionics, etc.
1601 int discharge_factor = 1;
1602 int discharge_rate = 1;
1603
1604 if( bio.charge_timer > 0 ) {
1605 bio.charge_timer -= discharge_rate;
1606 } else {
1607 if( bio.info().charge_time > 0 ) {
1608 if( bio.info().has_flag( STATIC( flag_str_id( "BIONIC_POWER_SOURCE" ) ) ) ) {
1609 // Convert fuel to bionic power
1610 burn_fuel( bio );
1611 // This is our first turn of charging, so subtract a turn from the recharge delay.
1612 bio.charge_timer = std::max( 0, bio.info().charge_time - 1 );
1613 } else {
1614 // Try to recharge our bionic if it is made for it
1615 units::energy cost = 0_J;
1616 bool recharged = attempt_recharge( *this, bio, cost, discharge_factor, discharge_rate );
1617 if( !recharged ) {
1618 // No power to recharge, so deactivate
1619 bio.powered = false;
1620 add_msg_if_player( m_neutral, _( "Your %s powers down." ), bio.info().name );
1621 // This purposely bypasses the deactivation cost
1622 deactivate_bionic( bio, true );
1623 return;
1624 }
1625 if( cost > 0_J ) {
1626 mod_power_level( -cost );
1627 }
1628 }
1629 }
1630 }
1631
1632 // Bionic effects on every turn they are active go here.
1633 if( bio.id == bio_remote ) {
1634 if( g->remoteveh() == nullptr && get_value( "remote_controlling" ).empty() ) {
1635 bio.powered = false;
1636 add_msg_if_player( m_warning, _( "Your %s has lost connection and is turning off." ),
1637 bio.info().name );
1638 }
1639 } else if( bio.id == bio_hydraulics ) {
1640 // Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
1641 sounds::sound( pos(), 19, sounds::sound_t::activity, _( "HISISSS!" ), false, "bionic",
1642 static_cast<std::string>( bio_hydraulics ) );
1643 } else if( bio.id == bio_nanobots ) {
1644 int threshold_kcal = bio.info().kcal_trigger > 0 ? 0.85f * max_stored_kcal() +
1645 bio.info().kcal_trigger : 0;
1646 const auto can_use_bionic = [this, &bio, threshold_kcal]() -> bool {
1647 const bool is_kcal_sufficient = get_stored_kcal() >= threshold_kcal;
1648 const bool is_power_sufficient = get_power_level() >= bio.info().power_trigger;
1649 return is_kcal_sufficient && is_power_sufficient;
1650 };
1651 if( get_stored_kcal() < threshold_kcal ) {
1652 bio.powered = false;
1653 add_msg_if_player( m_warning, _( "Your %s shut down to conserve calories." ), bio.info().name );
1654 deactivate_bionic( bio );
1655 return;
1656 }
1657 if( calendar::once_every( 30_turns ) ) {
1658 std::vector<effect *> bleeding_list = get_all_effects_of_type( effect_bleed );
1659 // Essential parts (Head/Torso) first.
1660 std::sort( bleeding_list.begin(), bleeding_list.end(),
1661 []( effect * a, effect * b ) {
1662 return a->get_bp()->essential > b->get_bp()->essential;
1663 } );
1664 if( !bleeding_list.empty() ) {
1665 effect *e = bleeding_list[0];
1666 if( e->get_intensity() > 1 ) {
1667 add_msg_if_player( "Your %s slow the bleeding on your %s", bio.info().name, e->get_bp()->name );
1668 e->mod_intensity( -1, false );
1669 } else {
1670 add_msg_if_player( "Your %s staunch the bleeding on your %s", bio.info().name, e->get_bp()->name );
1671 e->set_removed();
1672 }
1673 }
1674 if( calendar::once_every( 2_minutes ) ) {
1675 std::vector<bodypart_id> damaged_hp_parts;
1676 if( !damaged_hp_parts.empty() ) {
1677 // Essential parts are considered 10 HP lower than non-essential parts for the purpose of determining priority.
1678 // I'd use the essential_value, but it's tied up in the heal_actor class of iuse_actor.
1679 std::sort( damaged_hp_parts.begin(), damaged_hp_parts.end(),
1680 [this]( const bodypart_id & a, const bodypart_id & b ) {
1681 return ( get_part_hp_cur( a ) - a->essential * 10 ) < ( get_part_hp_cur( b ) - b->essential * 10 );
1682 } );
1683 for( bodypart_id &bpid : damaged_hp_parts ) {
1684 if( !can_use_bionic() ) {
1685 return;
1686 }
1687 heal( bpid, 1 );
1690 }
1691 }
1692 }
1693 }
1694 } else if( bio.id == bio_painkiller ) {
1695 const int pkill = get_painkiller();
1696 const int pain = get_pain();
1697 const units::energy trigger_cost = bio.info().power_trigger;
1698 int max_pkill = std::min( 150, pain );
1699 if( pkill < max_pkill ) {
1700 mod_painkiller( 1 );
1701 mod_power_level( -trigger_cost );
1702 }
1703
1704 // Only dull pain so extreme that we can't pkill it safely
1705 if( pkill >= 150 && pain > pkill && get_stim() > -150 ) {
1706 mod_pain( -1 );
1707 // Negative side effect: negative stim
1708 mod_stim( -1 );
1709 mod_power_level( -trigger_cost );
1710 }
1711 } else if( bio.id == bio_gills ) {
1712 if( has_effect( effect_asthma ) ) {
1714 _( "You feel your throat open up and air filling your lungs!" ) );
1716 }
1717 } else if( bio.id == bio_evap ) {
1718 // Aero-Evaporator provides water at 60 watts with 2 L / kWh efficiency
1719 // which is 10 mL per 5 minutes. Humidity can modify the amount gained.
1720 if( calendar::once_every( 5_minutes ) ) {
1721 const w_point &weatherPoint = get_weather().get_precise();
1722 int humidity = get_local_humidity( weatherPoint.humidity, get_weather().weather_id,
1723 g->is_sheltered( g->u.pos() ) );
1724 // in thirst units = 5 mL water
1725 int water_available = std::lround( humidity * 3.0 / 100.0 );
1726 // At 50% relative humidity or more, the player will draw 10 mL
1727 // At 16% relative humidity or less, the bionic will give up
1728 if( water_available == 0 ) {
1730 _( "There is not enough humidity in the air for your %s to function." ),
1731 bio.info().name );
1732 deactivate_bionic( bio );
1733 } else if( water_available == 1 ) {
1735 _( "Your %s issues a low humidity warning. Efficiency is reduced." ),
1736 bio.info().name );
1737 }
1738
1739 mod_thirst( -water_available );
1740 }
1741
1744 _( "You are properly hydrated. Your %s chirps happily." ),
1745 bio.info().name );
1746 deactivate_bionic( bio );
1747 }
1748 } else if( bio.id == bio_ads ) {
1749 if( bio.charge_timer < 2 ) {
1750 bio.charge_timer = 2;
1751 }
1752 if( bio.energy_stored < 150_kJ ) {
1753 // Max recharge rate is influenced by whether you've been hit or not.
1754 // See character.cpp for how charge_timer keeps track of that for this bionic.
1755 units::energy max_rate = 10_kJ;
1756 if( bio.charge_timer > 2 ) {
1757 max_rate /= 2;
1758 }
1759 units::energy ads_recharge = std::min( max_rate, 150_kJ - bio.energy_stored );
1760 if( ads_recharge < get_power_level() ) {
1761 mod_power_level( - ads_recharge );
1762 bio.energy_stored += ads_recharge;
1763 } else if( get_power_level() != 0_kJ ) {
1766 }
1767 if( bio.energy_stored == 150_kJ ) {
1768 add_msg_if_player( m_good, _( "Your %s quietens to a satisfied thrum." ), bio.info().name );
1769 }
1770 } else if( bio.energy_stored > 150_kJ ) {
1771 bio.energy_stored = 150_kJ;
1772 }
1773 } else if( bio.id == afs_bio_dopamine_stimulators ) {
1774 add_morale( MORALE_FEELING_GOOD, 20, 20, 30_minutes, 20_minutes, true );
1775 } else if( bio.id == bio_radscrubber ) {
1776 if( calendar::once_every( 10_minutes ) ) {
1777 const units::energy trigger_cost = bio.info().power_trigger;
1778
1779 if( get_rad() > 0 && bio.energy_stored >= trigger_cost ) {
1780 add_msg_if_player( m_good, _( "Your %s completed a scrubbing cycle." ), bio.info().name );
1781
1782 mod_rad( std::max( -10, -get_rad() ) );
1783 mod_power_level( -trigger_cost );
1784 }
1785 }
1786 }
1787}
static const efftype_id effect_bleed("bleed")
static bool attempt_recharge(Character &p, bionic &bio, units::energy &amount, int factor=1, int rate=1)
Definition: bionics.cpp:1547
static const efftype_id effect_asthma("asthma")
static const bionic_id afs_bio_dopamine_stimulators("afs_bio_dopamine_stimulators")
static const bionic_id bio_nanobots("bio_nanobots")
static const bionic_id bio_radscrubber("bio_radscrubber")
static const bionic_id bio_gills("bio_gills")
void mod_painkiller(int npkill)
Modifies intensity of painkillers
Definition: character.cpp:9793
void passive_power_gen(bionic &bio)
Passively produce power from PERPETUAL fuel.
Definition: bionics.cpp:1355
std::vector< const effect * > get_all_effects_of_type(const efftype_id &eff_id) const
Returns pointers to all effects matching given type.
Definition: creature.cpp:1271
void set_removed()
Definition: effect.h:252
constexpr double a
Definition: magic.cpp:1030
const morale_type MORALE_FEELING_GOOD("morale_feeling_good")
int kcal_trigger
Kcal cost when the bionic's special effect is triggered.
Definition: bionics.h:45
float get_auto_start_thresh() const
Definition: bionics.cpp:2801
bool is_auto_start_on() const
Definition: bionics.cpp:2806
translation name
Definition: bodypart.h:97

References _, a, sounds::activity, add_morale(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), afs_bio_dopamine_stimulators, attempt_recharge(), b, bio_ads, bio_evap, bio_gills, bio_hydraulics, bio_nanobots, bio_painkiller, bio_radscrubber, bio_remote, burn_fuel(), bionic_data::charge_time, bionic::charge_timer, deactivate_bionic(), effect_asthma, effect_bleed, bionic::energy_stored, find_remote_fuel(), flag_PERPETUAL(), bionic_data::fuel_opts, g, Creature::get_all_effects_of_type(), bionic::get_auto_start_thresh(), effect::get_bp(), get_fuel_available(), effect::get_intensity(), get_local_humidity(), get_max_power_level(), Creature::get_pain(), get_painkiller(), get_power_level(), weather_manager::get_precise(), get_rad(), get_stim(), get_stored_kcal(), get_thirst(), Creature::get_value(), get_weather(), Creature::has_effect(), bionic_data::has_flag(), Creature::has_flag(), heal(), w_point::humidity, hydrated, bionic::id, bionic::info(), bionic::is_auto_start_on(), string_id< T >::is_empty(), bionic_data::is_remote_fueled, bionic_data::kcal_trigger, m_bad, m_good, m_mixed, m_neutral, m_warning, max_stored_kcal(), effect::mod_intensity(), mod_pain(), mod_painkiller(), mod_power_level(), mod_rad(), mod_stim(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_GOOD, bionic_data::name, body_part_type::name, calendar::once_every(), Creature::pain, passive_power_gen(), pkill, pos(), bionic_data::power_trigger, bionic::powered, Creature::remove_effect(), effect::set_removed(), sounds::sound(), STATIC, and string_id< T >::str().

Referenced by suffer().

◆ process_effects_internal()

void Character::process_effects_internal ( )
overridevirtual

Processes human-specific effects of effects before calling Creature::process_effects().

Implements Creature.

Definition at line 538 of file character_turn.cpp.

539{
540 //Special Removals
541 if( has_effect( effect_darkness ) && g->is_in_sunlight( pos() ) ) {
543 }
545 vomit();
547 add_msg_if_player( m_bad, _( "We have mistakenly colonized a local guide! Purging now." ) );
548 }
559 add_msg_if_player( m_good, _( "Something writhes and inside of you as it dies." ) );
560 }
567 }
570 add_msg_if_player( m_good, _( "Your bowels gurgle as something inside them dies." ) );
571 }
572
573 //Human only effects
574 for( auto &elem : *effects ) {
575 for( auto &_effect_it : elem.second ) {
576 if( !_effect_it.second.is_removed() ) {
577 process_one_effect( _effect_it.second, false );
578 }
579 }
580 }
581}
static const efftype_id effect_bloodworms("bloodworms")
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_dermatik("dermatik")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const efftype_id effect_tapeworm("tapeworm")
static const trait_id trait_PARAIMMUNE("PARAIMMUNE")
static const efftype_id effect_darkness("darkness")
static const efftype_id effect_paincysts("paincysts")
static const trait_id trait_EATHEALTH("EATHEALTH")
static const trait_id trait_ACIDBLOOD("ACIDBLOOD")
static const efftype_id effect_brainworms("brainworms")
void process_one_effect(effect &it, bool is_new) override
Processes human-specific effects of an effect.

References _, Creature::add_msg_if_player(), effect_bloodworms, effect_brainworms, effect_darkness, effect_dermatik, effect_fungus, effect_paincysts, effect_tapeworm, Creature::effects, g, Creature::has_effect(), has_trait(), m_bad, m_good, pos(), process_one_effect(), Creature::remove_effect(), trait_ACIDBLOOD, trait_EATHEALTH, trait_M_IMMUNE, trait_PARAIMMUNE, and vomit().

◆ process_items()

void Character::process_items ( )

Process active items.

Definition at line 809 of file character_turn.cpp.

810{
811 item &weapon = primary_weapon();
812 if( weapon.needs_processing() && weapon.process( as_player(), pos(), false ) ) {
813 weapon = item();
814 }
815
816 std::vector<item *> inv_active = inv.active_items();
817 for( item *tmp_it : inv_active ) {
818 if( tmp_it->process( as_player(), pos(), false ) ) {
819 inv.remove_item( tmp_it );
820 }
821 }
822
823 // worn items
824 remove_worn_items_with( [this]( item & itm ) {
825 return itm.needs_processing() && itm.process( as_player(), pos(), false );
826 } );
827
828 // Active item processing done, now we're recharging.
829 std::vector<item *> active_worn_items;
830 bool weapon_active = weapon.has_flag( "USE_UPS" ) &&
831 weapon.charges < weapon.type->maximum_charges();
832 std::vector<size_t> active_held_items;
833 int ch_UPS = 0;
834 for( size_t index = 0; index < inv.size(); index++ ) {
835 item &it = inv.find_item( index );
836 itype_id identifier = it.type->get_id();
837 if( identifier == itype_UPS_off ) {
838 ch_UPS += it.ammo_remaining();
839 } else if( identifier == itype_adv_UPS_off ) {
840 ch_UPS += it.ammo_remaining() / 0.6;
841 }
842 if( it.has_flag( "USE_UPS" ) && it.charges < it.type->maximum_charges() ) {
843 active_held_items.push_back( index );
844 }
845 }
846 bool update_required = get_check_encumbrance();
847 for( item &w : worn ) {
848 if( w.has_flag( "USE_UPS" ) &&
849 w.charges < w.type->maximum_charges() ) {
850 active_worn_items.push_back( &w );
851 }
852 // Necessary for UPS in Aftershock - check worn items for charge
853 const itype_id &identifier = w.typeId();
854 if( identifier == itype_UPS_off ) {
855 ch_UPS += w.ammo_remaining();
856 } else if( identifier == itype_adv_UPS_off ) {
857 ch_UPS += w.ammo_remaining() / 0.6;
858 }
859 if( !update_required && w.encumbrance_update_ ) {
860 update_required = true;
861 }
862 w.encumbrance_update_ = false;
863 }
864 if( update_required ) {
866 }
867 if( has_active_bionic( bionic_id( "bio_ups" ) ) ) {
869 }
870 int ch_UPS_used = 0;
871
872 // Load all items that use the UPS to their minimal functional charge,
873 // The tool is not really useful if its charges are below charges_to_use
874 for( size_t index : active_held_items ) {
875 if( ch_UPS_used >= ch_UPS ) {
876 break;
877 }
878 item &it = inv.find_item( index );
879 ch_UPS_used++;
880 it.charges++;
881 }
882 if( weapon_active && ch_UPS_used < ch_UPS ) {
883 ch_UPS_used++;
884 weapon.charges++;
885 }
886 for( item *worn_item : active_worn_items ) {
887 if( ch_UPS_used >= ch_UPS ) {
888 break;
889 }
890 ch_UPS_used++;
891 worn_item->charges++;
892 }
893 if( ch_UPS_used > 0 ) {
894 use_charges( itype_UPS, ch_UPS_used );
895 }
896}
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const itype_id itype_UPS("UPS")
static const itype_id itype_UPS_off("UPS_off")
bool get_check_encumbrance() const
Definition: character.h:2018
std::vector< item * > active_items()
Definition: inventory.cpp:1090
size_t size() const
Definition: inventory.cpp:168
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9598
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8936
int maximum_charges() const
Definition: itype.cpp:123

References inventory::active_items(), item::ammo_remaining(), Creature::as_player(), bionic_id, item::charges, inventory::find_item(), get_check_encumbrance(), itype::get_id(), get_power_level(), has_active_bionic(), item::has_flag(), inv, itype_adv_UPS_off, itype_UPS, itype_UPS_off, itype::maximum_charges(), item::needs_processing(), pos(), primary_weapon(), item::process(), inventory::remove_item(), remove_worn_items_with(), reset_encumbrance(), inventory::size(), units::to_kilojoule(), item::type, use_charges(), and worn.

Referenced by npc::on_load(), and process_turn().

◆ process_one_effect()

void Character::process_one_effect ( effect it,
bool  is_new 
)
overridevirtual

Processes human-specific effects of an effect.

Implements Creature.

Definition at line 329 of file character_turn.cpp.

330{
331 bool reduced = resists_effect( it );
332 double mod = 1;
333 body_part bp = it.get_bp()->token;
334 int val = 0;
335
336 // Still hardcoded stuff, do this first since some modify their other traits
337 hardcoded_effects( it );
338
339 const auto get_effect = [&it, is_new]( const std::string & arg, bool reduced ) {
340 if( is_new ) {
341 return it.get_amount( arg, reduced );
342 }
343 return it.get_mod( arg, reduced );
344 };
345
346 // Handle miss messages
347 auto msgs = it.get_miss_msgs();
348 if( !msgs.empty() ) {
349 for( const auto &i : msgs ) {
350 add_miss_reason( _( i.first ), static_cast<unsigned>( i.second ) );
351 }
352 }
353
354 // Handle health mod
355 val = get_effect( "H_MOD", reduced );
356 if( val != 0 ) {
357 mod = 1;
358 if( is_new || it.activated( calendar::turn, "H_MOD", val, reduced, mod ) ) {
359 int bounded = bound_mod_to_vals(
360 get_healthy_mod(), val, it.get_max_val( "H_MOD", reduced ),
361 it.get_min_val( "H_MOD", reduced ) );
362 // This already applies bounds, so we pass them through.
363 mod_healthy_mod( bounded, get_healthy_mod() + bounded );
364 }
365 }
366
367 // Handle health
368 val = get_effect( "HEALTH", reduced );
369 if( val != 0 ) {
370 mod = 1;
371 if( is_new || it.activated( calendar::turn, "HEALTH", val, reduced, mod ) ) {
373 it.get_max_val( "HEALTH", reduced ), it.get_min_val( "HEALTH", reduced ) ) );
374 }
375 }
376
377 // Handle stim
378 val = get_effect( "STIM", reduced );
379 if( val != 0 ) {
380 mod = 1;
381 if( is_new || it.activated( calendar::turn, "STIM", val, reduced, mod ) ) {
382 mod_stim( bound_mod_to_vals( get_stim(), val, it.get_max_val( "STIM", reduced ),
383 it.get_min_val( "STIM", reduced ) ) );
384 }
385 }
386
387 // Handle hunger
388 val = get_effect( "HUNGER", reduced );
389 if( val != 0 ) {
390 mod = 1;
391 if( is_new || it.activated( calendar::turn, "HUNGER", val, reduced, mod ) ) {
393 val, it.get_max_val( "HUNGER", reduced ), it.get_min_val( "HUNGER", reduced ) ) );
394 }
395 }
396
397 // Handle thirst
398 val = get_effect( "THIRST", reduced );
399 if( val != 0 ) {
400 mod = 1;
401 if( is_new || it.activated( calendar::turn, "THIRST", val, reduced, mod ) ) {
402 mod_thirst( bound_mod_to_vals( get_thirst(), val, it.get_max_val( "THIRST", reduced ),
403 it.get_min_val( "THIRST", reduced ) ) );
404 }
405 }
406
407 // Handle fatigue
408 val = get_effect( "FATIGUE", reduced );
409 // Prevent ongoing fatigue effects while asleep.
410 // These are meant to change how fast you get tired, not how long you sleep.
411 if( val != 0 && !in_sleep_state() ) {
412 mod = 1;
413 if( is_new || it.activated( calendar::turn, "FATIGUE", val, reduced, mod ) ) {
414 mod_fatigue( bound_mod_to_vals( get_fatigue(), val, it.get_max_val( "FATIGUE", reduced ),
415 it.get_min_val( "FATIGUE", reduced ) ) );
416 }
417 }
418
419 // Handle Radiation
420 val = get_effect( "RAD", reduced );
421 if( val != 0 ) {
422 mod = 1;
423 if( is_new || it.activated( calendar::turn, "RAD", val, reduced, mod ) ) {
424 mod_rad( bound_mod_to_vals( get_rad(), val, it.get_max_val( "RAD", reduced ), 0 ) );
425 // Radiation can't go negative
426 if( get_rad() < 0 ) {
427 set_rad( 0 );
428 }
429 }
430 }
431
432 // Handle Pain
433 val = get_effect( "PAIN", reduced );
434 if( val != 0 ) {
435 mod = 1;
436 if( it.get_sizing( "PAIN" ) ) {
437 if( has_trait( trait_FAT ) ) {
438 mod *= 1.5;
439 }
440 if( get_size() == MS_LARGE ) {
441 mod *= 2;
442 }
443 if( get_size() == MS_HUGE ) {
444 mod *= 3;
445 }
446 }
447 if( is_new || it.activated( calendar::turn, "PAIN", val, reduced, mod ) ) {
448 int pain_inc = bound_mod_to_vals( get_pain(), val, it.get_max_val( "PAIN", reduced ), 0 );
449 mod_pain( pain_inc );
450 if( pain_inc > 0 ) {
451 character_funcs::add_pain_msg( *this, val, bp );
452 }
453 }
454 }
455
456 // Handle Damage
457 val = get_effect( "HURT", reduced );
458 if( val != 0 ) {
459 mod = 1;
460 if( it.get_sizing( "HURT" ) ) {
461 if( has_trait( trait_FAT ) ) {
462 mod *= 1.5;
463 }
464 if( get_size() == MS_LARGE ) {
465 mod *= 2;
466 }
467 if( get_size() == MS_HUGE ) {
468 mod *= 3;
469 }
470 }
471 if( is_new || it.activated( calendar::turn, "HURT", val, reduced, mod ) ) {
472 if( bp == num_bp ) {
473 if( val > 5 ) {
474 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp_torso ) );
475 } else {
476 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp_torso ) );
477 }
478 apply_damage( nullptr, bodypart_id( "torso" ), val, true );
479 } else {
480 if( val > 5 ) {
481 add_msg_if_player( _( "Your %s HURTS!" ), body_part_name_accusative( bp ) );
482 } else {
483 add_msg_if_player( _( "Your %s hurts!" ), body_part_name_accusative( bp ) );
484 }
485 apply_damage( nullptr, convert_bp( bp ).id(), val, true );
486 }
487 }
488 }
489
490 // Handle Sleep
491 val = get_effect( "SLEEP", reduced );
492 if( val != 0 ) {
493 mod = 1;
494 if( ( is_new || it.activated( calendar::turn, "SLEEP", val, reduced, mod ) ) &&
495 !has_effect( efftype_id( "sleep" ) ) ) {
496 add_msg_if_player( _( "You pass out!" ) );
498 }
499 }
500
501 // Handle painkillers
502 val = get_effect( "PKILL", reduced );
503 if( val != 0 ) {
505 if( is_new || it.activated( calendar::turn, "PKILL", val, reduced, mod ) ) {
506 mod_painkiller( bound_mod_to_vals( get_painkiller(), val, it.get_max_val( "PKILL", reduced ), 0 ) );
507 }
508 }
509
510 // Handle coughing
511 mod = 1;
512 val = 0;
513 if( it.activated( calendar::turn, "COUGH", val, reduced, mod ) ) {
514 cough( it.get_harmful_cough() );
515 }
516
517 // Handle vomiting
519 val = 0;
520 if( it.activated( calendar::turn, "VOMIT", val, reduced, mod ) ) {
521 vomit();
522 }
523
524 // Handle stamina
525 val = get_effect( "STAMINA", reduced );
526 if( val != 0 ) {
527 mod = 1;
528 if( is_new || it.activated( calendar::turn, "STAMINA", val, reduced, mod ) ) {
530 it.get_max_val( "STAMINA", reduced ),
531 it.get_min_val( "STAMINA", reduced ) ) );
532 }
533 }
534
535 // Speed and stats are handled in recalc_speed_bonus and reset_stats respectively
536}
int bound_mod_to_vals(int val, int mod, int max, int min)
Clamp the value of a modifier in order to bound the resulting value.
static const trait_id trait_FAT("FAT")
virtual int get_healthy_mod() const
Definition: character.cpp:4170
void cough(bool harmful=false, int loudness=4)
Definition: character.cpp:7553
void hardcoded_effects(effect &it)
Handles the still hard-coded effects.
int addiction_level(add_type type) const
Returns the intensity of the specified addiction.
Definition: suffer.cpp:1913
bool resists_effect(const effect &e) const
Returns true if the creature resists an effect.
Definition: creature.cpp:1351
bool get_sizing(const std::string &arg) const
Returns true if the given modifier type's trigger chance is affected by size mutations.
Definition: effect.cpp:1021
bool get_harmful_cough() const
Returns true if the coughs caused by an effect can harm the player directly.
Definition: effect.cpp:1199
int get_mod(std::string arg, bool reduced=false) const
Returns the matching modifier type from an effect, used for getting actual effect effects.
Definition: effect.cpp:910
int get_max_val(std::string arg, bool reduced=false) const
Returns the maximum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:1006
double get_addict_mod(const std::string &arg, int addict_level) const
Returns the modifier caused by addictions.
Definition: effect.cpp:1185
std::vector< std::pair< std::string, int > > get_miss_msgs() const
Returns a vector of the miss message messages and chances for use in add_miss_reason() while the effe...
Definition: effect.cpp:1216
bool activated(const time_point &when, std::string arg, int val, bool reduced=false, double mod=1) const
Checks to see if a given modifier type can activate, and performs any rolls required to do so.
Definition: effect.cpp:1108
int get_min_val(std::string arg, bool reduced=false) const
Returns the minimum value of a modifier type that get_mod() and get_amount() will push the player to.
Definition: effect.cpp:991
void add_pain_msg(const Character &who, int val, body_part bp)
Add message describing how character feels pain.

References _, effect::activated(), add_miss_reason(), Creature::add_msg_if_player(), character_funcs::add_pain_msg(), addiction_level(), apply_damage(), arg(), body_part_name_accusative(), bound_mod_to_vals(), bp_torso, convert_bp(), cough(), efftype_id, fall_asleep(), time_duration::from_turns(), effect::get_addict_mod(), effect::get_amount(), effect::get_bp(), Creature::get_effect(), get_fatigue(), effect::get_harmful_cough(), get_healthy(), get_healthy_mod(), effect::get_max_val(), effect::get_min_val(), effect::get_miss_msgs(), effect::get_mod(), Creature::get_pain(), get_painkiller(), get_rad(), get_size(), effect::get_sizing(), get_stamina(), get_stim(), get_stored_kcal(), get_thirst(), hardcoded_effects(), Creature::has_effect(), has_trait(), in_sleep_state(), max_stored_kcal(), mod_fatigue(), mod_healthy(), mod_healthy_mod(), mod_pain(), mod_painkiller(), mod_rad(), mod_stamina(), mod_stim(), mod_stored_kcal(), mod_thirst(), MS_HUGE, MS_LARGE, num_bp, PKILLER, Creature::resists_effect(), set_rad(), body_part_type::token, trait_FAT, calendar::turn, vomit(), and character_effects::vomit_mod().

Referenced by process_effects_internal().

◆ process_turn()

void Character::process_turn ( )
overridevirtual

Handles end-of-turn processing.

Reimplemented from Creature.

Reimplemented in npc.

Definition at line 161 of file character_turn.cpp.

162{
163 // Has to happen before reset_stats
165
166 for( bionic &i : *my_bionics ) {
167 if( i.incapacitated_time > 0_turns ) {
168 i.incapacitated_time -= 1_turns;
169 if( i.incapacitated_time == 0_turns ) {
170 add_msg_if_player( m_bad, _( "Your %s bionic comes back online." ), i.info().name );
171 }
172 }
173 }
174
176
177 // If we're actively handling something we can't just drop it on the ground
178 // in the middle of handling it
179 if( activity.targets.empty() ) {
181 }
183 // Didn't just pick something up
184 last_item = itype_id( "null" );
185
186 visit_items( [this]( item * e ) {
187 e->process_artifact( as_player(), pos() );
188 e->process_relic( *this );
189 return VisitResponse::NEXT;
190 } );
191
192 suffer();
193
194 // Handle player and NPC morale ticks
195
196 if( calendar::once_every( 1_minutes ) ) {
198 }
199
200 if( calendar::once_every( 9_turns ) ) {
202 }
203
204 // NPCs currently don't make any use of their scent, pointless to calculate it
205 // TODO: make use of NPC scent.
206 if( !is_npc() ) {
209 }
210 const int mask_intensity = get_effect_int( effect_masked_scent );
211
212 // Set our scent towards the norm
213 int norm_scent = 500;
214 int temp_norm_scent = INT_MIN;
215 bool found_intensity = false;
216 for( const trait_id &mut : get_mutations() ) {
217 const std::optional<int> &scent_intensity = mut->scent_intensity;
218 if( scent_intensity ) {
219 found_intensity = true;
220 temp_norm_scent = std::max( temp_norm_scent, *scent_intensity );
221 }
222 }
223 if( found_intensity ) {
224 norm_scent = temp_norm_scent;
225 }
226
227 for( const trait_id &mut : get_mutations() ) {
228 const std::optional<int> &scent_mask = mut->scent_mask;
229 if( scent_mask ) {
230 norm_scent += *scent_mask;
231 }
232 }
233
234 //mask from scent altering items;
235 norm_scent += mask_intensity;
236
237 // Scent increases fast at first, and slows down as it approaches normal levels.
238 // Estimate it will take about norm_scent * 2 turns to go from 0 - norm_scent / 2
239 // Without smelly trait this is about 1.5 hrs. Slows down significantly after that.
240 if( scent < rng( 0, norm_scent ) ) {
241 scent++;
242 }
243
244 // Unusually high scent decreases steadily until it reaches normal levels.
245 if( scent > norm_scent ) {
246 scent--;
247 }
248
249 for( const trait_id &mut : get_mutations() ) {
250 scent *= mut.obj().scent_modifier;
251 }
252 }
253
254 // We can dodge again! Assuming we can actually move...
255 if( in_sleep_state() ) {
256 blocks_left = 0;
257 dodges_left = 0;
258 } else if( moves > 0 ) {
261 }
262
263 // auto-learning. This is here because skill-increases happens all over the place:
264 // SkillLevel::readBook (has no connection to the skill or the player),
265 // player::read, player::practice, ...
266 // Check for spontaneous discovery of martial art styles
267 for( auto &style : autolearn_martialart_types() ) {
268 const matype_id &ma( style );
269
270 if( !martial_arts_data->has_martialart( ma ) && can_autolearn_martial_art( *this, ma ) ) {
271 martial_arts_data->add_martialart( ma );
272 add_msg_if_player( m_info, _( "You have learned a new style: %s!" ), ma.obj().name );
273 }
274 }
275
276 // Update time spent conscious in this overmap tile for the Nomad traits.
277 if( !is_npc() && ( has_trait( trait_NOMAD ) || has_trait( trait_NOMAD2 ) ||
278 has_trait( trait_NOMAD3 ) ) &&
281 const point_abs_omt pos = ompos.xy();
282 if( overmap_time.find( pos ) == overmap_time.end() ) {
283 overmap_time[pos] = 1_turns;
284 } else {
285 overmap_time[pos] += 1_turns;
286 }
287 }
288 // Decay time spent in other overmap tiles.
289 if( !is_npc() && calendar::once_every( 1_hours ) ) {
291 const time_point now = calendar::turn;
292 time_duration decay_time = 0_days;
293 if( has_trait( trait_NOMAD ) ) {
294 decay_time = 7_days;
295 } else if( has_trait( trait_NOMAD2 ) ) {
296 decay_time = 14_days;
297 } else if( has_trait( trait_NOMAD3 ) ) {
298 decay_time = 28_days;
299 }
300 auto it = overmap_time.begin();
301 while( it != overmap_time.end() ) {
302 if( it->first == ompos.xy() ) {
303 it++;
304 continue;
305 }
306 // Find the amount of time passed since the player touched any of the overmap tile's submaps.
307 const tripoint_abs_omt tpt( it->first, 0 );
308 const time_point last_touched = overmap_buffer.scent_at( tpt ).creation_time;
309 const time_duration since_visit = now - last_touched;
310 // If the player has spent little time in this overmap tile, let it decay after just an hour instead of the usual extended decay time.
311 const time_duration modified_decay_time = it->second > 5_minutes ? decay_time : 1_hours;
312 if( since_visit > modified_decay_time ) {
313 // Reduce the tracked time spent in this overmap tile.
314 const time_duration decay_amount = std::min( since_visit - modified_decay_time, 1_hours );
315 const time_duration updated_value = it->second - decay_amount;
316 if( updated_value <= 0_turns ) {
317 // We can stop tracking this tile if there's no longer any time recorded there.
318 it = overmap_time.erase( it );
319 continue;
320 } else {
321 it->second = updated_value;
322 }
323 }
324 it++;
325 }
326 }
327}
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_masked_scent("masked_scent")
static const trait_id trait_NOMAD2("NOMAD2")
static const trait_id trait_NOMAD3("NOMAD3")
static const trait_id trait_NOMAD("NOMAD")
static const efftype_id effect_sleep("sleep")
void update_morale()
Ticks down morale counters and removes them.
Definition: character.cpp:9007
void process_items()
Process active items.
void clear_miss_reasons()
Clears the list of reasons for why the player would miss a melee attack.
Definition: melee.cpp:385
void suffer()
Handles a large number of timers decrementing and other randomized effects.
Definition: suffer.cpp:1522
bool check_and_recover_morale()
Checks permanent morale for consistency and recovers it when an inconsistency is found.
Definition: character.cpp:9134
virtual void process_turn()
Processes effects and bonuses and allocates move points based on speed.
Definition: creature.cpp:154
virtual int get_num_dodges() const
Definition: creature.cpp:1485
virtual int get_num_blocks() const
Definition: creature.cpp:1481
void process_artifact(player *carrier, const tripoint &pos)
Process and apply artifact effects.
Definition: item.cpp:9068
void process_relic(Character &carrier)
Definition: item.cpp:9110
scent_trace scent_at(const tripoint_abs_omt &pos)
Method to retrieve the scent at a given location.
std::vector< item_location > targets
time_point creation_time
Definition: overmap_types.h:15
A point in the game time.
Definition: calendar.h:431
std::vector< matype_id > autolearn_martialart_types()
bool can_autolearn_martial_art(const Character &who, const matype_id &ma_id)
Returns true if the character can learn the entered martial art.

References _, activity, Creature::add_msg_if_player(), Creature::as_player(), autolearn_martialart_types(), blocks_left, can_autolearn_martial_art(), check_and_recover_morale(), clear_miss_reasons(), scent_trace::creation_time, dodges_left, drop_invalid_inventory(), effect_masked_scent, effect_narcosis, effect_sleep, Creature::get_effect_int(), get_mutations(), Creature::get_num_blocks(), Creature::get_num_dodges(), global_omt_location(), Creature::has_effect(), has_trait(), in_sleep_state(), Creature::is_npc(), itype_id, last_item, m_bad, m_info, martial_arts_data, Creature::moves, my_bionics, martialart::name, NEXT, string_id< T >::obj(), calendar::once_every(), overmap_buffer, overmap_time, pos(), item::process_artifact(), process_items(), item::process_relic(), Creature::process_turn(), restore_scent(), rng(), scent, overmapbuffer::scent_at(), suffer(), player_activity::targets, trait_NOMAD, trait_NOMAD2, trait_NOMAD3, calendar::turn, update_morale(), visitable< Character >::visit_items(), and coords::coord_point< Point, Origin, Scale >::xy().

Referenced by game::do_turn(), npc::process_turn(), and game::start_game().

◆ query_yn() [1/2]

template<typename ... Args>
bool Character::query_yn ( const char *const  msg,
Args &&...  args 
) const
inline

It is supposed to hide the query_yn to simplify player vs.

npc code.

Definition at line 1495 of file character.h.

1495 {
1496 return query_yn( string_format( msg, std::forward<Args>( args ) ... ) );
1497 }

References query_yn(), and string_format().

Referenced by activate_bionic(), can_install_bionics(), query_yn(), takeoff(), and will_eat().

◆ query_yn() [2/2]

virtual bool Character::query_yn ( const std::string &  msg) const
pure virtual

Implemented in npc, player, and player.

◆ ranged_dex_mod()

int Character::ranged_dex_mod ( ) const
virtual
Dexterity <20 increases ranged penalty

Definition at line 4154 of file character.cpp.

4155{
4156 ///\EFFECT_DEX <20 increases ranged penalty
4157 return std::max( ( 20.0 - get_dex() ) * 0.5, 0.0 );
4158}

References get_dex().

Referenced by draw_stats_info(), ranged::get_weapon_dispersion(), and set_stats().

◆ ranged_per_mod()

int Character::ranged_per_mod ( ) const
virtual
Perception <20 increases ranged aiming penalty.

Definition at line 4160 of file character.cpp.

4161{
4162 ///\EFFECT_PER <20 increases ranged aiming penalty.
4163 return std::max( ( 20.0 - get_per() ) * 1.2, 0.0 );
4164}

References get_per().

Referenced by draw_stats_info(), ranged::effective_dispersion(), and set_stats().

◆ reach_attack()

void Character::reach_attack ( const tripoint p)

Handles reach melee attack on point p.

Melee >5 allows WHIP_DISARM technique Stabbing decreases chance of hitting intervening target on reach attack Stabbing increases ability to reach attack through fences Strength increases bash effects when reach attacking past something

Definition at line 677 of file melee.cpp.

678{
679 matec_id force_technique = tec_none;
680 /** @EFFECT_MELEE >5 allows WHIP_DISARM technique */
681 if( primary_weapon().has_flag( "WHIP" ) && ( get_skill_level( skill_melee ) > 5 ) && one_in( 3 ) ) {
682 force_technique = matec_id( "WHIP_DISARM" );
683 }
684
685 map &here = get_map();
686 Creature *critter = g->critter_at( p );
687 // Original target size, used when there are monsters in front of our target
688 int target_size = critter != nullptr ? ( critter->get_size() + 1 ) : 2;
689 // Reset last target pos
690 as_player()->last_target_pos = std::nullopt;
691 // Max out recoil
693
695 int skill = std::min( 10, get_skill_level( skill_stabbing ) );
696 int t = 0;
697 std::vector<tripoint> path = line_to( pos(), p, t, 0 );
698 tripoint last_point = pos();
699 path.pop_back(); // Last point is our critter
700 for( const tripoint &path_point : path ) {
701 // Possibly hit some unintended target instead
702 Creature *inter = g->critter_at( path_point );
703 int inter_block_size = inter != nullptr ? ( inter->get_size() + 1 ) : 2;
704 /** @EFFECT_STABBING decreases chance of hitting intervening target on reach attack */
705 if( inter != nullptr &&
706 !x_in_y( ( target_size * target_size + 1 ) * skill,
707 ( inter_block_size * inter_block_size + 1 ) * 10 ) ) {
708 // Even if we miss here, low roll means weapon is pushed away or something like that
709 critter = inter;
710 break;
711 } else if( here.obstructed_by_vehicle_rotation( last_point, path_point ) ) {
712 tripoint rand = path_point;
713 if( one_in( 2 ) ) {
714 rand.x = last_point.x;
715 } else {
716 rand.y = last_point.y;
717 }
718
719 here.bash( rand, str_cur + primary_weapon().damage_melee( DT_BASH ) );
722 return;
723 /** @EFFECT_STABBING increases ability to reach attack through fences */
724 } else if( here.impassable( path_point ) &&
725 // Fences etc. Spears can stab through those
726 !( primary_weapon().has_flag( "SPEAR" ) &&
727 g->m.has_flag( "THIN_OBSTACLE", path_point ) &&
728 x_in_y( skill, 10 ) ) ) {
729 /** @EFFECT_STR increases bash effects when reach attacking past something */
730 here.bash( path_point, str_cur + primary_weapon().damage_melee( DT_BASH ) );
733 return;
734 }
735 last_point = path_point;
736 }
737
738 if( here.obstructed_by_vehicle_rotation( last_point, p ) ) {
739 tripoint rand = p;
740 if( one_in( 2 ) ) {
741 rand.x = last_point.x;
742 } else {
743 rand.y = last_point.y;
744 }
745
746 here.bash( rand, str_cur + primary_weapon().damage_melee( DT_BASH ) );
749 return;
750 }
751
752 if( critter == nullptr ) {
753 add_msg_if_player( _( "You swing at the air." ) );
754 if( martial_arts_data->has_miss_recovery_tec( primary_weapon() ) ) {
755 move_cost /= 3; // "Probing" is faster than a regular miss
756 }
757
759 return;
760 }
761
762 reach_attacking = true;
763 melee_attack( *critter, false, &force_technique, false );
764 reach_attacking = false;
765}
virtual m_size get_size() const =0
std::optional< tripoint > last_target_pos
Definition: player.h:242
static const skill_id skill_stabbing("stabbing")
string_id< ma_technique > matec_id
Definition: type_id.h:92

References _, Creature::add_msg_if_player(), Creature::as_player(), attack_cost(), item::damage_melee(), DT_BASH, g, get_map(), Creature::get_size(), get_skill_level(), handle_melee_wear(), Creature::has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), player::last_target_pos, line_to(), martial_arts_data, MAX_RECOIL, melee_attack(), Creature::mod_moves(), move_cost(), one_in(), pos(), primary_weapon(), reach_attacking, recoil, skill_melee, skill_stabbing, str_cur, tec_none, tripoint::x, x_in_y(), and tripoint::y.

Referenced by npc::execute_action(), and reach_attack().

◆ react_to_felt_pain()

void Character::react_to_felt_pain ( int  intensity)

Definition at line 740 of file character.cpp.

741{
742 if( intensity <= 0 ) {
743 return;
744 }
745 if( is_player() && intensity >= 2 ) {
746 g->cancel_activity_or_ignore_query( distraction_type::pain, _( "Ouch, something hurts!" ) );
747 }
748 // Only a large pain burst will actually wake people while sleeping.
750 int pain_thresh = rng( 3, 5 );
751
753 pain_thresh += 2;
754 } else if( has_trait( trait_HEAVYSLEEPER2 ) ) {
755 pain_thresh += 5;
756 }
757
758 if( intensity >= pain_thresh ) {
759 wake_up();
760 }
761 }
762}
static const trait_id trait_HEAVYSLEEPER("HEAVYSLEEPER")
static const trait_id trait_HEAVYSLEEPER2("HEAVYSLEEPER2")

References _, effect_narcosis, effect_sleep, g, Creature::has_effect(), has_trait(), Creature::is_player(), pain, rng(), trait_HEAVYSLEEPER, trait_HEAVYSLEEPER2, and wake_up().

Referenced by set_pain(), and set_painkiller().

◆ read_speed()

int Character::read_speed ( bool  return_stat_effect = true) const

Returns the player's reading speed.

Intelligence increases reading speed by 3s per level above 8

Definition at line 3501 of file character.cpp.

3502{
3503 // Stat window shows stat effects on based on current stat
3504 const int intel = get_int();
3505 /** @EFFECT_INT increases reading speed by 3s per level above 8*/
3506 int ret = to_moves<int>( 1_minutes ) - to_moves<int>( 3_seconds ) * ( intel - 8 );
3507
3509 ret *= .75;
3510 }
3511
3512 ret *= mutation_value( "reading_speed_multiplier" );
3513
3514 if( ret < to_moves<int>( 1_seconds ) ) {
3515 ret = to_moves<int>( 1_seconds );
3516 }
3517 // return_stat_effect actually matters here
3518 return return_stat_effect ? ret : ret * 100 / to_moves<int>( 1_minutes );
3519}
static const bionic_id afs_bio_linguistic_coprocessor("afs_bio_linguistic_coprocessor")

References afs_bio_linguistic_coprocessor, get_int(), has_bionic(), mutation_value(), and cata::hash64_detail::ret.

Referenced by draw_stats_info(), read_inventory_preset::read_inventory_preset(), set_stats(), npc::time_to_read(), and avatar::time_to_read().

◆ rebuild_mutation_cache()

void Character::rebuild_mutation_cache ( )

Definition at line 7904 of file character.cpp.

7905{
7906 cached_mutations.clear();
7907 for( const std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
7908 cached_mutations.push_back( &mut.first.obj() );
7909 }
7910 for( const trait_id &mut : enchantment_cache->get_mutations() ) {
7911 cached_mutations.push_back( &mut.obj() );
7912 }
7913}

References cached_mutations, enchantment_cache, and my_mutations.

Referenced by set_mutation(), and unset_mutation().

◆ recalc_hp()

void Character::recalc_hp ( )

Recalculates HP after a change to max strength.

Definition at line 1583 of file character.cpp.

1584{
1585 int str_boost_val = 0;
1586 std::optional<skill_boost> str_boost = skill_boost::get( "str" );
1587 if( str_boost ) {
1588 int skill_total = 0;
1589 for( const std::string &skill_str : str_boost->skills() ) {
1590 skill_total += get_skill_level( skill_id( skill_str ) );
1591 }
1592 str_boost_val = str_boost->calc_bonus( skill_total );
1593 }
1594 // Mutated toughness stacks with starting, by design.
1595 float hp_mod = 1.0f + mutation_value( "hp_modifier" ) + mutation_value( "hp_modifier_secondary" );
1596 float hp_adjustment = mutation_value( "hp_adjustment" ) + ( str_boost_val * 3 );
1597 calc_all_parts_hp( hp_mod, hp_adjustment, get_str_base() );
1598}
void calc_all_parts_hp(float hp_mod=0.0, float hp_adjust=0.0, int str_max=0)
Sets hp for all body parts.
Definition: character.cpp:1600
static std::optional< skill_boost > get(const std::string &stat_str)
Definition: skill_boost.cpp:20

References calc_all_parts_hp(), skill_boost::get(), get_skill_level(), get_str_base(), mutation_value(), and skill_id.

Referenced by apply_mods(), apply_skill_boost(), avatar::create(), mutation_effect(), mutation_loss_effect(), character_funcs::normalize(), npc::randomize(), reset_scenario(), set_stats(), standard_npc::standard_npc(), and avatar::upgrade_stat().

◆ recalc_sight_limits()

void Character::recalc_sight_limits ( )

Modifies the player's sight values Must be called when any of the following change: This must be called when any of the following change:

  • effects
  • bionics
  • traits
  • underwater
  • clothes

Definition at line 1630 of file character.cpp.

1631{
1632 sight_max = 9999;
1633 vision_mode_cache.reset();
1634
1635 // Set sight_max.
1636 if( is_blind() || ( in_sleep_state() && !has_trait( trait_SEESLEEP ) ) ||
1638 sight_max = 0;
1639 } else if( has_effect( effect_boomered ) && ( !( has_trait( trait_PER_SLIME_OK ) ) ) ) {
1640 sight_max = 1;
1642 } else if( has_effect( effect_in_pit ) || has_effect( effect_no_sight ) ||
1646 sight_max = 1;
1647 } else if( has_active_mutation( trait_SHELL2 ) ) {
1648 // You can kinda see out a bit.
1649 sight_max = 2;
1650 } else if( ( has_trait( trait_MYOPIC ) || has_trait( trait_URSINE_EYE ) ) &&
1652 sight_max = 4;
1653 } else if( has_trait( trait_PER_SLIME ) ) {
1654 sight_max = 6;
1655 } else if( has_effect( effect_darkness ) ) {
1657 sight_max = 10;
1658 }
1659
1660 // Debug-only NV
1663 }
1664
1665 float best_bonus_nv = 0.0f;
1666 for( const mutation_branch *mut : cached_mutations ) {
1667 best_bonus_nv = std::max( best_bonus_nv, mut->night_vision_range );
1668 }
1670 ( is_mounted() && mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1671 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1672 }
1673 if( has_nv() ) {
1675 best_bonus_nv = std::max( best_bonus_nv, 10.0f );
1676 }
1677 if( has_trait( trait_BIRD_EYE ) ) {
1679 }
1680 if( has_trait( trait_URSINE_EYE ) ) {
1682 }
1683
1684 // +1 because of the ugly -1 in _from_per
1687 nv_range += best_bonus_nv;
1689 nv_range++;
1690 }
1691
1692 // Not exactly a sight limit thing, but related enough
1697 mounted_creature->has_flag( MF_MECH_RECON_VISION ) ) ) {
1699 }
1700
1702 has_effect_with_flag( "EFFECT_SUPER_CLAIRVOYANCE" ) ) {
1705 has_effect_with_flag( "EFFECT_CLAIRVOYANCE_PLUS" ) ) {
1707 } else if( has_artifact_with( AEP_CLAIRVOYANCE ) ||
1708 has_effect_with_flag( "EFFECT_CLAIRVOYANCE" ) ) {
1710 }
1711}
static const bionic_id bio_infrared("bio_infrared")
static const std::string flag_FIX_NEARSIGHT("FIX_NEARSIGHT")
static const efftype_id effect_contacts("contacts")
static const trait_id trait_CEPH_EYES("CEPH_EYES")
static const trait_id trait_INFRARED("INFRARED")
static const trait_id trait_LIZ_IR("LIZ_IR")
static const trait_id trait_URSINE_EYE("URSINE_EYE")
static const trait_id trait_MEMBRANE("MEMBRANE")
static const trait_id trait_MYOPIC("MYOPIC")
static const trait_id trait_BIRD_EYE("BIRD_EYE")
static const efftype_id effect_darkness("darkness")
static const bionic_id bio_membrane("bio_membrane")
static const std::string flag_SWIM_GOGGLES("SWIM_GOGGLES")
static const std::string flag_IR_EFFECT("IR_EFFECT")
static const trait_id trait_DEBUG_NIGHTVISION("DEBUG_NIGHTVISION")
static const trait_id trait_PER_SLIME_OK("PER_SLIME_OK")
static const efftype_id effect_no_sight("no_sight")
bool has_nv()
Returns true if the player has some form of night vision.
Definition: character.cpp:3653
int sight_max
Definition: character.h:2181
@ AEP_CLAIRVOYANCE_PLUS
Definition: enums.h:142
@ AEP_SUPER_CLAIRVOYANCE
Definition: enums.h:112
@ AEP_CLAIRVOYANCE
Definition: enums.h:111
float nv_range_from_per(int per)
Definition: character.cpp:1723
float nv_range_from_eye_encumbrance(int enc)
Definition: character.cpp:1729

References AEP_CLAIRVOYANCE, AEP_CLAIRVOYANCE_PLUS, AEP_SUPER_CLAIRVOYANCE, bio_infrared, bio_membrane, BIRD_EYE, BOOMERED, bp_eyes, cached_mutations, DARKNESS, DEBUG_NIGHTVISION, effect_boomered, effect_contacts, effect_darkness, effect_in_pit, effect_narcosis, effect_no_sight, encumb(), flag_FIX_NEARSIGHT(), flag_IR_EFFECT(), flag_SWIM_GOGGLES(), get_per(), has_active_bionic(), has_active_mutation(), has_artifact_with(), has_bionic(), Creature::has_effect(), Creature::has_effect_with_flag(), has_nv(), has_trait(), in_sleep_state(), IR_VISION, is_blind(), is_mounted(), Creature::is_underwater(), is_wearing(), itype_rm13_armor_on, MF_MECH_RECON_VISION, mounted_creature, NV_GOGGLES, nv_range, vision::nv_range_from_eye_encumbrance(), vision::nv_range_from_per(), sight_max, trait_BIRD_EYE, trait_CEPH_EYES, trait_DEBUG_NIGHTVISION, trait_INFRARED, trait_LIZ_IR, trait_MEMBRANE, trait_MYOPIC, trait_PER_SLIME, trait_PER_SLIME_OK, trait_SEESLEEP, trait_SHELL2, trait_URSINE_EYE, URSINE_VISION, VISION_CLAIRVOYANCE, VISION_CLAIRVOYANCE_PLUS, VISION_CLAIRVOYANCE_SUPER, vision_mode_cache, and worn_with_flag().

Referenced by add_bionic(), deactivate_mutation(), environmental_revert_effect(), load(), game::load(), mount_creature(), mutation_spend_resources(), on_item_takeoff(), on_item_wear(), player::player(), remove_bionic(), reset_stats(), set_mutation(), set_underwater(), takeoff(), unset_mutation(), wake_up(), and wear_item().

◆ recalc_speed_bonus()

void Character::recalc_speed_bonus ( )

Calculates the various speed bonuses we will get from mutations, etc.

Definition at line 95 of file character_turn.cpp.

96{
97 // Minus some for weight...
98 int carry_penalty = 0;
99 if( weight_carried() > weight_capacity() && !has_trait( trait_id( "DEBUG_STORAGE" ) ) ) {
100 carry_penalty = 25 * ( weight_carried() - weight_capacity() ) / ( weight_capacity() );
101 }
102 mod_speed_bonus( -carry_penalty );
103
105
108 }
109 // when underweight, you get slower. cumulative with hunger
111
112 for( const auto &maps : *effects ) {
113 for( auto &i : maps.second ) {
114 if( i.second.is_removed() ) {
115 continue;
116 }
117 bool reduced = resists_effect( i.second );
118 mod_speed_bonus( i.second.get_mod( "SPEED", reduced ) );
119 }
120 }
121
122 // add martial arts speed bonus
124
125 // Not sure why Sunlight Dependent is here, but OK
126 // Ectothermic/COLDBLOOD4 is intended to buff folks in the Summer
127 // Threshold-crossing has its charms ;-)
128 if( g != nullptr ) {
129 if( has_trait( trait_SUNLIGHT_DEPENDENT ) && !g->is_in_sunlight( pos() ) ) {
130 mod_speed_bonus( -( g->light_level( posz() ) >= 12 ? 5 : 10 ) );
131 }
132 const float temperature_speed_modifier = mutation_value( "temperature_speed_modifier" );
133 if( temperature_speed_modifier != 0 ) {
134 const auto player_local_temp = get_weather().get_temperature( pos() );
135 if( has_trait( trait_COLDBLOOD4 ) || player_local_temp < 65 ) {
136 mod_speed_bonus( ( player_local_temp - 65 ) * temperature_speed_modifier );
137 }
138 }
139 }
140
142 mod_speed_bonus( 20 );
143 }
145 mod_speed_bonus( -20 );
146 }
147
149
150 float speed_modifier = Character::mutation_value( "speed_modifier" );
151 mod_speed_mult( speed_modifier - 1 );
152
153 if( has_bionic( bio_speed ) ) { // add 10% speed bonus
154 mod_speed_mult( 0.1 );
155 }
156
157 double ench_bonus = enchantment_cache->calc_bonus( enchant_vals::mod::SPEED, get_speed() );
158 mod_speed_bonus( ench_bonus );
159}
int get_speedydex_bonus(const int dex)
Returns value of speedydex bonus if enabled.
Definition: character.cpp:4140
static const trait_id trait_COLDBLOOD4("COLDBLOOD4")
static const trait_id trait_SUNLIGHT_DEPENDENT("SUNLIGHT_DEPENDENT")
static const bionic_id bio_speed("bio_speed")
int mabuff_speed_bonus() const
Returns the speed bonus from martial arts buffs.
virtual void mod_speed_mult(float nspeed)
Definition: creature.cpp:1817
virtual void mod_speed_bonus(int nspeed)
Definition: creature.cpp:1813
@ AEP_SPEED_UP
Definition: enums.h:107
@ AEP_SPEED_DOWN
Definition: enums.h:137
int get_thirst_speed_penalty(int thirst)
Returns the penalty to speed from thirst.
int get_kcal_speed_penalty(float kcal_percent)
Returns the penalty to speed from starvation.
stat_mod get_pain_penalty(const Character &ch)
Returns the effect of pain on stats.

References AEP_SPEED_DOWN, AEP_SPEED_UP, bio_speed, Creature::effects, enchantment_cache, g, get_dex(), get_kcal_percent(), character_effects::get_kcal_speed_penalty(), character_effects::get_pain_penalty(), get_speed(), get_speedydex_bonus(), weather_manager::get_temperature(), get_thirst(), character_effects::get_thirst_speed_penalty(), get_weather(), has_artifact_with(), has_bionic(), has_trait(), mabuff_speed_bonus(), Creature::mod_speed_bonus(), Creature::mod_speed_mult(), mutation_value(), pos(), posz(), Creature::resists_effect(), stat_mod::speed, enchant_vals::SPEED, trait_COLDBLOOD4, trait_id, trait_SUNLIGHT_DEPENDENT, very_thirsty, weight_capacity(), and weight_carried().

Referenced by reset_stats().

◆ recalculate_enchantment_cache()

void Character::recalculate_enchantment_cache ( )

Definition at line 7863 of file character.cpp.

7864{
7865 // start by resetting the cache
7867
7868 visit_items( [&]( const item * it ) {
7869 for( const enchantment &ench : it->get_enchantments() ) {
7870 if( ench.is_active( *this, *it ) ) {
7871 enchantment_cache->force_add( ench );
7872 }
7873 }
7874 return VisitResponse::NEXT;
7875 } );
7876
7877 // get from traits/ mutations
7878 for( const std::pair<const trait_id, char_trait_data> &mut_map : my_mutations ) {
7879 const mutation_branch &mut = mut_map.first.obj();
7880
7881 for( const enchantment_id &ench_id : mut.enchantments ) {
7882 const enchantment &ench = ench_id.obj();
7883 if( ench.is_active( *this, mut.activated && mut_map.second.powered ) ) {
7884 enchantment_cache->force_add( ench );
7885 }
7886 }
7887 }
7888
7889 for( const bionic &bio : *my_bionics ) {
7890 const bionic_id &bid = bio.id;
7891
7892 for( const enchantment_id &ench_id : bid->enchantments ) {
7893 const enchantment &ench = ench_id.obj();
7894 if( ench.is_active( *this, bio.powered &&
7895 bid->has_flag( STATIC( flag_str_id( "BIONIC_TOGGLED" ) ) ) ) ) {
7896 enchantment_cache->force_add( ench );
7897 }
7898 }
7899 }
7900
7902}
void rebuild_mutation_cache()
Definition: character.cpp:7904
bool is_active(const Character &guy, const item &parent) const
const std::vector< enchantment > & get_enchantments() const
Definition: item.cpp:6988
bool activated
Definition: mutation.h:93

References enchantment_cache, item::get_enchantments(), NEXT, and visitable< Character >::visit_items().

Referenced by activate_bionic(), activate_mutation(), add_bionic(), deactivate_bionic(), deactivate_mutation(), on_mutation_gain(), on_mutation_loss(), remove_bionic(), reset(), update_body(), and avatar_funcs::use_item().

◆ recalculate_size()

void Character::recalculate_size ( )

Recalculate size class of character.

Definition at line 244 of file mutation.cpp.

245{
247 // Only one size-changing mutation is expected, so it will only use the first one it finds.
248 for( const mutation_branch *mut : cached_mutations ) {
249 if( mut->body_size ) {
250 size_class = *mut->body_size;
251 break;
252 }
253 }
254}

References cached_mutations, MS_MEDIUM, and size_class.

Referenced by load(), mutation_effect(), and mutation_loss_effect().

◆ reduce_healing_effect()

int Character::reduce_healing_effect ( const efftype_id eff_id,
int  remove_med,
const bodypart_id hurt 
)

Reduce healing effect intensity, return initial intensity of the effect.

Definition at line 8623 of file character.cpp.

8625{
8626 const body_part hurt_token = hurt->token;
8627 effect &e = get_effect( eff_id, hurt_token );
8628 int intensity = e.get_intensity();
8629 if( remove_med < intensity ) {
8630 if( eff_id == effect_bandaged ) {
8631 add_msg_if_player( m_bad, _( "Bandages on your %s were damaged!" ), body_part_name( hurt_token ) );
8632 } else if( eff_id == effect_disinfected ) {
8633 add_msg_if_player( m_bad, _( "You got some filth on your disinfected %s!" ),
8634 body_part_name( hurt_token ) );
8635 }
8636 } else {
8637 if( eff_id == effect_bandaged ) {
8638 add_msg_if_player( m_bad, _( "Bandages on your %s were destroyed!" ),
8639 body_part_name( hurt_token ) );
8640 } else if( eff_id == effect_disinfected ) {
8641 add_msg_if_player( m_bad, _( "Your %s is no longer disinfected!" ), body_part_name( hurt_token ) );
8642 }
8643 }
8644 e.mod_duration( -6_hours * remove_med );
8645 return intensity;
8646}

References _, Creature::add_msg_if_player(), body_part_name(), effect_bandaged, effect_disinfected, Creature::get_effect(), effect::get_intensity(), m_bad, and effect::mod_duration().

Referenced by apply_damage().

◆ regen()

void Character::regen ( int  rate_multiplier)

Handles passive regeneration of pain and maybe hp.

Definition at line 4573 of file character.cpp.

4574{
4575 int pain_ticks = rate_multiplier;
4576 while( get_pain() > 0 && pain_ticks-- > 0 ) {
4577 mod_pain( -roll_remainder( ( 0.2f + get_pain() / 50.0f ) * ( 1.0f +
4578 mutation_value( "pain_recovery" ) ) ) );
4579 }
4580
4581 float rest = rest_quality();
4582 float heal_rate = healing_rate( rest ) * to_turns<int>( 5_minutes );
4583 const float broken_regen_mod = clamp( mutation_value( "mending_modifier" ), 0.25f, 1.0f );
4584 if( heal_rate > 0.0f ) {
4585 const int base_heal = roll_remainder( rate_multiplier * heal_rate );
4586 const int broken_heal = roll_remainder( base_heal * broken_regen_mod );
4587
4588 for( const bodypart_id &bp : get_all_body_parts() ) {
4589 const bool is_broken = is_limb_broken( bp ) &&
4591 heal( bp, is_broken ? broken_heal : base_heal );
4592 mod_part_healed_total( bp, is_broken ? broken_heal : base_heal );
4593 }
4594 } else if( heal_rate < 0.0f ) {
4595 int rot_rate = roll_remainder( rate_multiplier * -heal_rate );
4596 // Has to be in loop because some effects depend on rounding
4597 while( rot_rate-- > 0 ) {
4598 hurtall( 1, nullptr, false );
4599 }
4600 }
4601
4602 // include healing effects
4603 for( int i = 0; i < num_hp_parts; i++ ) {
4604 const bodypart_id &bp = convert_bp( hp_to_bp( static_cast<hp_part>( i ) ) ).id();
4605 float healing = healing_rate_medicine( rest, bp ) * to_turns<int>( 5_minutes );
4606
4607 const bool is_broken = is_limb_broken( bp ) &&
4609 const int healing_apply = roll_remainder( is_broken ? healing *broken_regen_mod : healing );
4610
4611 healed_bp( i, healing_apply );
4612 heal( bp, healing_apply );
4613
4614 if( damage_bandaged[i] > 0 ) {
4615 damage_bandaged[i] -= healing_apply;
4616 if( damage_bandaged[i] <= 0 ) {
4617 damage_bandaged[i] = 0;
4618 remove_effect( effect_bandaged, bp->token );
4619 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4620 }
4621 }
4622 if( damage_disinfected[i] > 0 ) {
4623 damage_disinfected[i] -= healing_apply;
4624 if( damage_disinfected[i] <= 0 ) {
4625 damage_disinfected[i] = 0;
4626 remove_effect( effect_disinfected, bp->token );
4627 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4628 }
4629 }
4630
4631 // remove effects if the limb was healed by other way
4632 if( has_effect( effect_bandaged, bp->token ) && ( get_part( bp ).is_at_max_hp() ) ) {
4633 damage_bandaged[i] = 0;
4634 remove_effect( effect_bandaged, bp->token );
4635 add_msg_if_player( _( "Bandaged wounds on your %s healed." ), body_part_name( bp ) );
4636 }
4637 if( has_effect( effect_disinfected, bp->token ) && ( get_part( bp ).is_at_max_hp() ) ) {
4638 damage_disinfected[i] = 0;
4639 remove_effect( effect_disinfected, bp->token );
4640 add_msg_if_player( _( "Disinfected wounds on your %s healed." ), body_part_name( bp ) );
4641 }
4642 }
4643
4644 if( get_rad() > 0 ) {
4645 mod_rad( -roll_remainder( rate_multiplier / 50.0f ) );
4646 }
4647}
float healing_rate(float at_rest_quality) const
Average hit points healed per turn.
Definition: character.cpp:6663
float healing_rate_medicine(float at_rest_quality, const bodypart_id &bp) const
Average hit points healed per turn from healing effects.
Definition: character.cpp:6705
float rest_quality() const
Returns >0 if character is sitting/lying and relatively inactive.
Definition: character.cpp:6454
void healed_bp(int bp, int amount)
Definition: character.cpp:7751

References _, Creature::add_msg_if_player(), body_part_name(), clamp(), convert_bp(), damage_bandaged, damage_disinfected, effect_bandaged, effect_disinfected, flag_SPLINT(), Creature::get_all_body_parts(), Creature::get_pain(), Creature::get_part(), get_rad(), Creature::has_effect(), heal(), healed_bp(), healing_rate(), healing_rate_medicine(), hp_to_bp(), hurtall(), string_id< T >::id(), is_limb_broken(), mod_pain(), Creature::mod_part_healed_total(), mod_rad(), mutation_value(), num_hp_parts, Creature::remove_effect(), rest_quality(), roll_remainder(), and worn_with_flag().

Referenced by update_body().

◆ rem_addiction()

void Character::rem_addiction ( add_type  type)

Removes an addition from the player.

Definition at line 1900 of file suffer.cpp.

1901{
1902 auto iter = std::find_if( addictions.begin(), addictions.end(),
1903 [type]( const addiction & ad ) {
1904 return ad.type == type;
1905 } );
1906
1907 if( iter != addictions.end() ) {
1908 addictions.erase( iter );
1909 g->events().send<event_type::loses_addiction>( getID(), type );
1910 }
1911}

References addictions, g, getID(), loses_addiction, and type.

Referenced by marloss_common(), iuse::mycus(), and suffer_from_addictions().

◆ rem_morale()

void Character::rem_morale ( const morale_type type)

◆ remove_bionic()

void Character::remove_bionic ( const bionic_id b)

Removes a bionic from my_bionics[].

Definition at line 2634 of file bionics.cpp.

2635{
2636 bionic_collection new_my_bionics;
2637 // any spells you should not forget due to still having a bionic installed that has it.
2638 std::set<spell_id> cbm_spells;
2639 for( bionic &i : *my_bionics ) {
2640 if( b == i.id ) {
2641 continue;
2642 }
2643
2644 // Linked bionics: if either is removed, the other is removed as well.
2645 if( b->is_included( i.id ) || i.id->is_included( b ) ) {
2646 continue;
2647 }
2648
2649 for( const std::pair<const spell_id, int> &spell_pair : i.id->learned_spells ) {
2650 cbm_spells.emplace( spell_pair.first );
2651 }
2652
2653 new_my_bionics.push_back( bionic( i.id, i.invlet ) );
2654 }
2655
2656 // any spells you learn from installing a bionic you forget.
2657 for( const std::pair<const spell_id, int> &spell_pair : b->learned_spells ) {
2658 if( cbm_spells.count( spell_pair.first ) == 0 ) {
2659 magic->forget_spell( spell_pair.first );
2660 }
2661 }
2662
2663 *my_bionics = new_my_bionics;
2666 if( !b->enchantments.empty() ) {
2668 }
2669}

References b, magic, my_bionics, recalc_sight_limits(), recalculate_enchantment_cache(), and reset_encumbrance().

Referenced by perform_install(), perform_uninstall(), and uninstall_bionic().

◆ remove_child_flag()

void Character::remove_child_flag ( const trait_id flag)

Removes the mutation's child flag from the player's list.

Definition at line 1471 of file mutation.cpp.

1472{
1473 for( auto &elem : flag->replacements ) {
1474 const trait_id &tmp = elem;
1475 if( has_trait( tmp ) ) {
1476 remove_mutation( tmp );
1477 return;
1478 } else if( has_child_flag( tmp ) ) {
1479 remove_child_flag( tmp );
1480 return;
1481 }
1482 }
1483}

References has_child_flag(), has_trait(), remove_child_flag(), remove_mutation(), and mutation_branch::replacements.

Referenced by mutate_towards(), and remove_child_flag().

◆ remove_mission_items()

void Character::remove_mission_items ( int  mission_id)

Definition at line 2530 of file character.cpp.

2531{
2532 if( mission_id == -1 ) {
2533 return;
2534 }
2535 remove_items_with( has_mission_item_filter { mission_id } );
2536}

References visitable< Character >::remove_items_with().

◆ remove_mutation()

void Character::remove_mutation ( const trait_id mut,
bool  silent = false 
)

Removes a mutation, downgrading to the previous level if possible.

Definition at line 1313 of file mutation.cpp.

1314{
1315 const auto &mdata = mut.obj();
1316 // Check if there's a prerequisite we should shrink back into
1317 trait_id replacing = trait_id::NULL_ID();
1318 std::vector<trait_id> originals = mdata.prereqs;
1319 for( size_t i = 0; !replacing && i < originals.size(); i++ ) {
1320 trait_id pre = originals[i];
1321 const auto &p = pre.obj();
1322 for( size_t j = 0; !replacing && j < p.replacements.size(); j++ ) {
1323 if( p.replacements[j] == mut ) {
1324 replacing = pre;
1325 }
1326 }
1327 }
1328
1329 trait_id replacing2 = trait_id::NULL_ID();
1330 std::vector<trait_id> originals2 = mdata.prereqs2;
1331 for( size_t i = 0; !replacing2 && i < originals2.size(); i++ ) {
1332 trait_id pre2 = originals2[i];
1333 const auto &p = pre2.obj();
1334 for( size_t j = 0; !replacing2 && j < p.replacements.size(); j++ ) {
1335 if( p.replacements[j] == mut ) {
1336 replacing2 = pre2;
1337 }
1338 }
1339 }
1340
1341 // See if this mutation is canceled by a base trait
1342 //Only if there's no prerequisite to shrink to, thus we're at the bottom of the trait line
1343 if( !replacing ) {
1344 //Check each mutation until we reach the end or find a trait to revert to
1345 for( auto &iter : mutation_branch::get_all() ) {
1346 //See if it's in our list of base traits but not active
1347 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1348 //See if that base trait cancels the mutation we are using
1349 std::vector<trait_id> traitcheck = iter.cancels;
1350 if( !traitcheck.empty() ) {
1351 for( size_t j = 0; !replacing && j < traitcheck.size(); j++ ) {
1352 if( traitcheck[j] == mut ) {
1353 replacing = ( iter.id );
1354 }
1355 }
1356 }
1357 }
1358 if( replacing ) {
1359 break;
1360 }
1361 }
1362 }
1363
1364 // Duplicated for prereq2
1365 if( !replacing2 ) {
1366 //Check each mutation until we reach the end or find a trait to revert to
1367 for( auto &iter : mutation_branch::get_all() ) {
1368 //See if it's in our list of base traits but not active
1369 if( has_base_trait( iter.id ) && !has_trait( iter.id ) ) {
1370 //See if that base trait cancels the mutation we are using
1371 std::vector<trait_id> traitcheck = iter.cancels;
1372 if( !traitcheck.empty() ) {
1373 for( size_t j = 0; !replacing2 && j < traitcheck.size(); j++ ) {
1374 if( traitcheck[j] == mut && ( iter.id ) != replacing ) {
1375 replacing2 = ( iter.id );
1376 }
1377 }
1378 }
1379 }
1380 if( replacing2 ) {
1381 break;
1382 }
1383 }
1384 }
1385
1386 // make sure we don't toggle a mutation or trait twice, or it will cancel itself out.
1387 if( replacing == replacing2 ) {
1388 replacing2 = trait_id::NULL_ID();
1389 }
1390
1391 // This should revert back to a removed base trait rather than simply removing the mutation
1392 unset_mutation( mut );
1393
1394 bool mutation_replaced = false;
1395
1396 game_message_type rating;
1397
1398 if( replacing ) {
1399 const auto &replace_mdata = replacing.obj();
1400 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1401 rating = m_mixed;
1402 } else if( replace_mdata.points - mdata.points > 0 ) {
1403 rating = m_good;
1404 } else if( mdata.points - replace_mdata.points > 0 ) {
1405 rating = m_bad;
1406 } else {
1407 rating = m_neutral;
1408 }
1409 if( !silent ) {
1410 add_msg_player_or_npc( rating,
1411 _( "Your %1$s mutation turns into %2$s." ),
1412 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1413 mdata.name(), replace_mdata.name() );
1414 }
1415 set_mutation( replacing );
1416 mutation_replaced = true;
1417 }
1418 if( replacing2 ) {
1419 const auto &replace_mdata = replacing2.obj();
1420 if( mdata.mixed_effect || replace_mdata.mixed_effect ) {
1421 rating = m_mixed;
1422 } else if( replace_mdata.points - mdata.points > 0 ) {
1423 rating = m_good;
1424 } else if( mdata.points - replace_mdata.points > 0 ) {
1425 rating = m_bad;
1426 } else {
1427 rating = m_neutral;
1428 }
1429 if( !silent ) {
1430 add_msg_player_or_npc( rating,
1431 _( "Your %1$s mutation turns into %2$s." ),
1432 _( "<npcname>'s %1$s mutation turns into %2$s." ),
1433 mdata.name(), replace_mdata.name() );
1434 }
1435 set_mutation( replacing2 );
1436 mutation_replaced = true;
1437 }
1438 if( !mutation_replaced ) {
1439 if( mdata.mixed_effect ) {
1440 rating = m_mixed;
1441 } else if( mdata.points > 0 ) {
1442 rating = m_bad;
1443 } else if( mdata.points < 0 ) {
1444 rating = m_good;
1445 } else {
1446 rating = m_neutral;
1447 }
1448 if( !silent ) {
1449 add_msg_player_or_npc( rating,
1450 _( "You lose your %s mutation." ),
1451 _( "<npcname> loses their %s mutation." ),
1452 mdata.name() );
1453 }
1454 }
1455
1458}
@ silent
Definition: weather_type.h:56

References _, Creature::add_msg_player_or_npc(), drench_mut_calc(), mutation_branch::get_all(), has_base_trait(), has_trait(), m_bad, m_good, m_mixed, m_neutral, string_id< mutation_branch >::NULL_ID(), string_id< T >::obj(), set_highest_cat_level(), set_mutation(), silent, and unset_mutation().

Referenced by do_purify(), player::load(), mutate(), mutate_towards(), old_mutate(), perform_install(), iuse::purify_iv(), iuse::purify_smart(), remove_child_flag(), and debug_menu::wishmutate().

◆ remove_weapon()

◆ remove_worn_items_with()

std::list< item > Character::remove_worn_items_with ( std::function< bool(item &)>  filter)

Similar to remove_items_with, but considers only worn items and not their content (item::contents is not checked).

If the filter function returns true, the item is removed.

Definition at line 2295 of file character.cpp.

2296{
2297 std::list<item> result;
2298 for( auto iter = worn.begin(); iter != worn.end(); ) {
2299 if( filter( *iter ) ) {
2300 iter->on_takeoff( *this );
2301 result.splice( result.begin(), worn, iter++ );
2302 } else {
2303 ++iter;
2304 }
2305 }
2306 return result;
2307}

References worn.

Referenced by mutation_effect(), and process_items().

◆ reset()

void Character::reset ( )
overridevirtual

Handles stat and bonus reset.

Reimplemented from Creature.

Definition at line 3646 of file character.cpp.

3647{
3649 // TODO: Move reset_stats here, remove it from Creature
3651}
virtual void reset()
Handles stat and bonus reset.
Definition: creature.cpp:122

References recalculate_enchantment_cache(), and Creature::reset().

Referenced by activate_bionic(), deactivate_bionic(), game::load(), and set_stats().

◆ reset_bonuses()

void Character::reset_bonuses ( )
overridevirtual

Resets the value of all bonus fields to 0.

Reimplemented from Creature.

Definition at line 4550 of file character.cpp.

4551{
4552 // Reset all bonuses to 0 and multipliers to 1.0
4553 str_bonus = 0;
4554 dex_bonus = 0;
4555 per_bonus = 0;
4556 int_bonus = 0;
4557
4559}
virtual void reset_bonuses()
Resets the value of all bonus fields to 0.
Definition: creature.cpp:136

References dex_bonus, int_bonus, per_bonus, Creature::reset_bonuses(), and str_bonus.

◆ reset_chargen_attributes()

void Character::reset_chargen_attributes ( )

Definition at line 6779 of file character.cpp.

6780{
6781 init_age = 25;
6782 init_height = 175;
6783}

References init_age, and init_height.

◆ reset_encumbrance()

◆ reset_remote_fuel()

void Character::reset_remote_fuel ( )

Definition at line 1488 of file bionics.cpp.

1489{
1490 if( get_bionic_fueled_with( item( fuel_type_sun_light ) ).empty() ) {
1491 remove_value( "sunlight" );
1492 }
1493 remove_value( "rem_battery" );
1494}

References fuel_type_sun_light, get_bionic_fueled_with(), and Creature::remove_value().

Referenced by iuse::cable_attach(), and deactivate_bionic().

◆ reset_stats()

void Character::reset_stats ( )
overridevirtual

Resets stats, and applies effects in an idempotent manner.

Implements Creature.

Definition at line 583 of file character_turn.cpp.

584{
585 const int current_stim = get_stim();
586
587 // Trait / mutation buffs
589 add_miss_reason( _( "Your thick scales get in the way." ), 2 );
590 }
592 add_miss_reason( _( "Your chitin gets in the way." ), 1 );
593 }
595 mod_per_bonus( 2 );
596 }
598 add_miss_reason( _( "Your insect limbs get in the way." ), 2 );
599 }
601 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
602 mod_dex_bonus( 1 );
603 } else {
604 mod_dex_bonus( -1 );
605 add_miss_reason( _( "Your clothing restricts your insect arms." ), 1 );
606 }
607 }
608 if( has_trait( trait_WEBBED ) ) {
609 add_miss_reason( _( "Your webbed hands get in the way." ), 1 );
610 }
612 add_miss_reason( _( "Your arachnid limbs get in the way." ), 4 );
613 }
615 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
616 mod_dex_bonus( 2 );
617 } else if( !exclusive_flag_coverage( "OVERSIZE" ).test( bp_torso ) ) {
618 mod_dex_bonus( -2 );
619 add_miss_reason( _( "Your clothing constricts your arachnid limbs." ), 2 );
620 }
621 }
622 const auto set_fake_effect_dur = [this]( const efftype_id & type, const time_duration & dur ) {
623 effect &eff = get_effect( type );
624 if( eff.get_duration() == dur ) {
625 return;
626 }
627
628 if( eff.is_null() && dur > 0_turns ) {
629 add_effect( type, dur, num_bp );
630 } else if( dur > 0_turns ) {
631 eff.set_duration( dur );
632 } else {
634 }
635 };
636 // Painkiller
637 set_fake_effect_dur( effect_pkill, 1_turns * get_painkiller() );
638
639 // Pain
640 if( get_perceived_pain() > 0 ) {
641 const stat_mod ppen = character_effects::get_pain_penalty( *this );
642 mod_str_bonus( -ppen.strength );
643 mod_dex_bonus( -ppen.dexterity );
645 mod_per_bonus( -ppen.perception );
646 if( ppen.dexterity > 0 ) {
647 add_miss_reason( _( "Your pain distracts you!" ), static_cast<unsigned>( ppen.dexterity ) );
648 }
649 }
650
651 // Radiation
652 set_fake_effect_dur( effect_irradiated, 1_turns * get_rad() );
653 // Morale
654 const int morale = get_morale_level();
655 set_fake_effect_dur( effect_happy, 1_turns * morale );
656 set_fake_effect_dur( effect_sad, 1_turns * -morale );
657
658 // Stimulants
659 set_fake_effect_dur( effect_stim, 1_turns * current_stim );
660 set_fake_effect_dur( effect_depressants, 1_turns * -current_stim );
661 if( has_trait( trait_STIMBOOST ) ) {
662 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 60 ) );
663 } else {
664 set_fake_effect_dur( effect_stim_overdose, 1_turns * ( current_stim - 30 ) );
665 }
666 // Starvation
667 if( get_kcal_percent() < 0.95f ) {
668 // kcal->percentage of base str
669 static const std::vector<std::pair<float, float>> starv_thresholds = { {
670 std::make_pair( 0.0f, 0.5f ),
671 std::make_pair( 0.8f, 0.1f ),
672 std::make_pair( 0.95f, 0.0f )
673 }
674 };
675
676 const int str_penalty = std::floor( multi_lerp( starv_thresholds, get_kcal_percent() ) );
677 add_miss_reason( _( "You're weak from hunger." ),
678 static_cast<unsigned>( str_penalty / 2 ) );
679 mod_str_bonus( -str_penalty );
680 mod_dex_bonus( -( str_penalty / 2 ) );
681 mod_int_bonus( -( str_penalty / 2 ) );
682 }
683 // Thirst
684 set_fake_effect_dur( effect_thirsty, 1_turns * ( get_thirst() - thirst_levels::very_thirsty ) );
686 set_fake_effect_dur( effect_sleep_deprived, 1_turns * get_sleep_deprivation() );
687 } else if( has_effect( effect_sleep_deprived ) ) {
689 }
690
691 // Dodge-related effects
693 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) / 20.0f - encumb( bp_torso ) / 10.0f );
694 // Whiskers don't work so well if they're covered
695 if( has_trait( trait_WHISKERS ) && !wearing_something_on( bodypart_id( "mouth" ) ) ) {
696 mod_dodge_bonus( 1.5 );
697 }
699 mod_dodge_bonus( 3 );
700 }
701 // depending on mounts size, attacks will hit the mount and use their dodge rating.
702 // if they hit the player, the player cannot dodge as effectively.
703 if( is_mounted() ) {
704 mod_dodge_bonus( -4 );
705 }
706 // Spider hair is basically a full-body set of whiskers, once you get the brain for it
708 static const std::array<bodypart_id, 5> parts{ { bodypart_id( "head" ), bodypart_id( "arm_r" ), bodypart_id( "arm_l" ), bodypart_id( "leg_r" ), bodypart_id( "leg_l" ) } };
709 for( const bodypart_id &bp : parts ) {
710 if( !wearing_something_on( bp ) ) {
711 mod_dodge_bonus( +1 );
712 }
713 }
714 // Torso handled separately, bigger bonus
715 if( !wearing_something_on( bodypart_id( "torso" ) ) ) {
716 mod_dodge_bonus( 4 );
717 }
718 }
719
720 // Apply static martial arts buffs
721 martial_arts_data->ma_static_effects( *this );
722
723 if( calendar::once_every( 1_minutes ) ) {
725 }
726
727 // Effects
728 for( const auto &maps : *effects ) {
729 for( auto i : maps.second ) {
730 const auto &it = i.second;
731 if( it.is_removed() ) {
732 continue;
733 }
734 bool reduced = resists_effect( it );
735 mod_str_bonus( it.get_mod( "STR", reduced ) );
736 mod_dex_bonus( it.get_mod( "DEX", reduced ) );
737 mod_per_bonus( it.get_mod( "PER", reduced ) );
738 mod_int_bonus( it.get_mod( "INT", reduced ) );
739 }
740 }
741
742 // Bionic buffs
744 mod_str_bonus( 20 );
745 }
746
751
752 // Trait / mutation buffs
753 mod_str_bonus( std::floor( mutation_value( "str_modifier" ) ) );
754 mod_dodge_bonus( std::floor( mutation_value( "dodge_modifier" ) ) );
755
757
758 nv_cached = false;
759
760 // Reset our stats to normal levels
761 // Any persistent buffs/debuffs will take place in effects,
762 // player::suffer(), etc.
763
764 // repopulate the stat fields
769
770 // Floor for our stats. No stat changes should occur after this!
771 if( dex_cur < 0 ) {
772 dex_cur = 0;
773 }
774 if( str_cur < 0 ) {
775 str_cur = 0;
776 }
777 if( per_cur < 0 ) {
778 per_cur = 0;
779 }
780 if( int_cur < 0 ) {
781 int_cur = 0;
782 }
783
786}
float multi_lerp(const std::vector< std::pair< float, float > > &points, float x)
From points, finds p1 and p2 such that p1.first < x < p2.first Then linearly interpolates between p1....
static const efftype_id effect_sad("sad")
static const efftype_id effect_pkill("pkill")
static const trait_id trait_ARACHNID_ARMS("ARACHNID_ARMS")
static const trait_id trait_THICK_SCALES("THICK_SCALES")
static const trait_id trait_COMPOUND_EYES("COMPOUND_EYES")
static const trait_id trait_WEBBED("WEBBED")
static const bionic_id bio_hydraulics("bio_hydraulics")
static const efftype_id effect_irradiated("irradiated")
static const trait_id trait_CHITIN3("CHITIN3")
static const trait_id trait_CHITIN2("CHITIN2")
static const trait_id trait_STIMBOOST("STIMBOOST")
static const trait_id trait_CHITIN_FUR3("CHITIN_FUR3")
static const trait_id trait_WHISKERS("WHISKERS")
static const efftype_id effect_thirsty("thirsty")
static const trait_id trait_WHISKERS_RAT("WHISKERS_RAT")
static const trait_id trait_INSECT_ARMS_OK("INSECT_ARMS_OK")
static const trait_id trait_ARACHNID_ARMS_OK("ARACHNID_ARMS_OK")
static const efftype_id effect_stim_overdose("stim_overdose")
static const efftype_id effect_stim("stim")
static const efftype_id effect_happy("happy")
static const efftype_id effect_depressants("depressants")
static const efftype_id effect_sleep_deprived("sleep_deprived")
static const trait_id trait_INSECT_ARMS("INSECT_ARMS")
virtual int get_str_bonus() const
Definition: character.cpp:4123
virtual int get_int_bonus() const
Definition: character.cpp:4135
int get_mod_stat_from_bionic(const character_stat &Stat) const
Get stat bonus from bionic.
Definition: character.cpp:2116
float mabuff_dodge_bonus() const
Returns the dodge bonus from martial arts buffs.
virtual int get_per_bonus() const
Definition: character.cpp:4131
void apply_skill_boost()
Applies skill-based boosts to stats.
Definition: character.cpp:3569
void recalc_speed_bonus()
Calculates the various speed bonuses we will get from mutations, etc.
virtual int get_dex_bonus() const
Definition: character.cpp:4127
virtual void mod_dodge_bonus(float ndodge)
Definition: creature.cpp:1821
void update_mental_focus(Character &who)
Uses calc_focus_change to update the player's current focus.

References _, Creature::add_effect(), add_miss_reason(), apply_skill_boost(), bio_hydraulics, bp_leg_l, bp_leg_r, bp_torso, dex_cur, dex_max, stat_mod::dexterity, DEXTERITY, effect_depressants, effect_happy, effect_irradiated, effect_pkill, effect_sad, effect_sleep_deprived, effect_stim, effect_stim_overdose, effect_thirsty, Creature::effects, encumb(), exclusive_flag_coverage(), get_dex_bonus(), effect::get_duration(), Creature::get_effect(), get_int_bonus(), get_kcal_percent(), get_mod_stat_from_bionic(), get_morale_level(), character_effects::get_pain_penalty(), get_painkiller(), get_per_bonus(), get_perceived_pain(), get_rad(), get_sleep_deprivation(), get_stim(), get_str_bonus(), get_thirst(), harmless, has_active_bionic(), Creature::has_effect(), has_trait(), int_cur, int_max, stat_mod::intelligence, INTELLIGENCE, is_mounted(), effect::is_null(), mabuff_dodge_bonus(), martial_arts_data, mod_dex_bonus(), Creature::mod_dodge_bonus(), mod_int_bonus(), mod_per_bonus(), mod_str_bonus(), morale, multi_lerp(), mutation_value(), num_bp, nv_cached, calendar::once_every(), per_cur, per_max, stat_mod::perception, PERCEPTION, recalc_sight_limits(), recalc_speed_bonus(), Creature::remove_effect(), Creature::resists_effect(), effect::set_duration(), str_cur, str_max, stat_mod::strength, STRENGTH, trait_ARACHNID_ARMS, trait_ARACHNID_ARMS_OK, trait_CHITIN2, trait_CHITIN3, trait_CHITIN_FUR3, trait_COMPOUND_EYES, trait_INSECT_ARMS, trait_INSECT_ARMS_OK, trait_STIMBOOST, trait_THICK_SCALES, trait_WEBBED, trait_WHISKERS, trait_WHISKERS_RAT, type, character_funcs::update_mental_focus(), very_thirsty, and wearing_something_on().

Referenced by debug_menu::character_edit_menu().

◆ rest_quality()

float Character::rest_quality ( ) const

Returns >0 if character is sitting/lying and relatively inactive.

1 represents sleep on comfortable bed, so anything above that should be rare.

Definition at line 6454 of file character.cpp.

6455{
6456 // Just a placeholder for now.
6457 // TODO: Waiting/reading/being unconscious on bed/sofa/grass
6458 return has_effect( effect_sleep ) ? 1.0f : 0.0f;
6459}

References effect_sleep, and Creature::has_effect().

Referenced by regen().

◆ restore_scent()

void Character::restore_scent ( )

restore scent after masked_scent effect run out or is removed by water

Definition at line 8771 of file character.cpp.

8772{
8773 const std::string prev_scent = get_value( "prev_scent" );
8774 if( !prev_scent.empty() ) {
8776 set_type_of_scent( scenttype_id( prev_scent ) );
8777 remove_value( "prev_scent" );
8778 remove_value( "waterproof_scent" );
8779 add_msg_if_player( m_info, _( "You smell like yourself again." ) );
8780 }
8781}
static const efftype_id effect_masked_scent("masked_scent")
void set_type_of_scent(const scenttype_id &id)
Definition: character.cpp:8761
string_id< scent_type > scenttype_id
Definition: type_id.h:42

References _, Creature::add_msg_if_player(), effect_masked_scent, Creature::get_value(), m_info, Creature::remove_effect(), Creature::remove_value(), and set_type_of_scent().

Referenced by drench(), and process_turn().

◆ resume_backlog_activity()

void Character::resume_backlog_activity ( )

Definition at line 9271 of file character.cpp.

9272{
9273 if( !backlog.empty() && backlog.front().auto_resume ) {
9274 activity = backlog.front();
9275 backlog.pop_front();
9276 }
9277}

References activity, and backlog.

Referenced by game::cancel_activity_query(), and player_activity::do_turn().

◆ roll_all_damage()

void Character::roll_all_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds all 3 types of physical damage to instance.

Definition at line 412 of file melee.cpp.

414{
415 roll_bash_damage( crit, di, average, weap );
416 roll_cut_damage( crit, di, average, weap );
417 roll_stab_damage( crit, di, average, weap );
418}
void roll_stab_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total stab damage to the damage instance.
Definition: melee.cpp:1107
void roll_bash_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total bash damage to the damage instance.
Definition: melee.cpp:929
void roll_cut_damage(bool crit, damage_instance &di, bool average, const item &weap) const
Adds player's total cut damage to the damage instance.
Definition: melee.cpp:1033

References roll_bash_damage(), roll_cut_damage(), and roll_stab_damage().

Referenced by item::combat_info(), item::effective_dps(), and melee_attack().

◆ roll_bash_damage()

void Character::roll_bash_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total bash damage to the damage instance.

Strength increases bashing damage Strength increases bashing damage Unarmed caps bash damage with unarmed weapons Bashing caps bash damage with bashing weapons Strength boosts low cap on bashing damage

Definition at line 929 of file melee.cpp.

931{
932 float bash_dam = 0.0f;
933
934 const bool unarmed = weap.is_unarmed_weapon();
935 int skill = get_skill_level( unarmed ? skill_unarmed : skill_bashing );
936 if( has_active_bionic( bio_cqb ) ) {
937 skill = BIO_CQB_LEVEL;
938 }
939
940 const int stat = get_str();
941 /** @EFFECT_STR increases bashing damage */
942 float stat_bonus = bonus_damage( !average );
943 stat_bonus += mabuff_damage_bonus( DT_BASH );
944
945 // Drunken Master damage bonuses
947 // Remember, a single drink gives 600 levels of "drunk"
948 int mindrunk = 0;
949 int maxdrunk = 0;
950 const time_duration drunk_dur = get_effect_dur( effect_drunk );
951 if( unarmed ) {
952 mindrunk = drunk_dur / 1_hours;
953 maxdrunk = drunk_dur / 25_minutes;
954 } else {
955 mindrunk = drunk_dur / 90_minutes;
956 maxdrunk = drunk_dur / 40_minutes;
957 }
958
959 bash_dam += average ? ( mindrunk + maxdrunk ) * 0.5f : rng( mindrunk, maxdrunk );
960 }
961
962 if( unarmed ) {
963 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
964 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
965 weap.is_null();
966 if( left_empty || right_empty ) {
967 float per_hand = 0.0f;
968 for( const trait_id &mut : get_mutations() ) {
969 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
970 continue;
971 }
972 float unarmed_bonus = 0.0f;
973 const int bash_bonus = mut->bash_dmg_bonus;
974 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && bash_bonus > 0 ) {
975 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
976 }
977 per_hand += bash_bonus + unarmed_bonus;
978 const std::pair<int, int> rand_bash = mut->rand_bash_bonus;
979 per_hand += average ? ( rand_bash.first + rand_bash.second ) / 2.0f : rng( rand_bash.first,
980 rand_bash.second );
981 }
982 bash_dam += per_hand; // First hand
983 if( left_empty && right_empty ) {
984 // Second hand
985 bash_dam += per_hand;
986 }
987 }
988
989 }
990
991 /** @EFFECT_STR increases bashing damage */
992 float weap_dam = weap.damage_melee( DT_BASH ) + stat_bonus;
993 /** @EFFECT_UNARMED caps bash damage with unarmed weapons */
994
995 /** @EFFECT_BASHING caps bash damage with bashing weapons */
996 float bash_cap = 2 * stat + 2 * skill;
997 float bash_mul = 1.0f;
998
999 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
1000 if( skill < 5 ) {
1001 bash_mul = 0.8 + 0.08 * skill;
1002 } else {
1003 bash_mul = 0.96 + 0.04 * skill;
1004 }
1005
1006 if( bash_cap < weap_dam && !weap.is_null() ) {
1007 // If damage goes over cap due to low stats/skills,
1008 // scale the post-armor damage down halfway between damage and cap
1009 bash_mul *= ( 1.0f + ( bash_cap / weap_dam ) ) / 2.0f;
1010 }
1011
1012 /** @EFFECT_STR boosts low cap on bashing damage */
1013 const float low_cap = std::min( 1.0f, stat / 20.0f );
1014 const float bash_min = low_cap * weap_dam;
1015 weap_dam = average ? ( bash_min + weap_dam ) * 0.5f : rng_float( bash_min, weap_dam );
1016
1017 bash_dam += weap_dam;
1018 bash_mul *= mabuff_damage_mult( DT_BASH );
1019
1020 float armor_mult = 1.0f;
1021 int arpen = mabuff_arpen_bonus( DT_BASH );
1022
1023 // Finally, extra critical effects
1024 if( crit ) {
1025 bash_mul *= 1.5f;
1026 // 50% armor penetration
1027 armor_mult = 0.5f;
1028 }
1029
1030 di.add_damage( DT_BASH, bash_dam, arpen, armor_mult, bash_mul );
1031}
int mabuff_arpen_bonus(damage_type type) const
Returns the arpen bonus from martial arts buffs.
float bonus_damage(bool random) const
Returns the bonus bashing damage the player deals based on their stats.
Definition: melee.cpp:919
bool natural_attack_restricted_on(const bodypart_id &bp) const
Returns true if the character is wearing something on the entered body_part, ignoring items with the ...
Definition: character.cpp:1783
int mabuff_damage_bonus(damage_type type) const
Returns the flat damage bonus to given type from martial arts buffs, applied after the multiplier.
float mabuff_damage_mult(damage_type type) const
Returns the damage multiplier to given type from martial arts buffs.
static const efftype_id effect_drunk("drunk")
static const trait_id trait_DRUNKEN("DRUNKEN")
static const skill_id skill_bashing("bashing")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bonus_damage(), item::damage_melee(), DT_BASH, effect_drunk, Creature::get_effect_dur(), get_mutations(), get_skill_level(), get_str(), has_active_bionic(), has_active_mutation(), Creature::has_effect(), has_trait(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), rng_float(), skill_bashing, skill_unarmed, and trait_DRUNKEN.

Referenced by roll_all_damage().

◆ roll_cut_damage()

void Character::roll_cut_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total cut damage to the damage instance.

Cutting increases cutting damage multiplier

Definition at line 1033 of file melee.cpp.

1035{
1036 float cut_dam = mabuff_damage_bonus( DT_CUT ) + weap.damage_melee( DT_CUT );
1037 float cut_mul = 1.0f;
1038
1039 int cutting_skill = get_skill_level( skill_cutting );
1040
1041 if( has_active_bionic( bio_cqb ) ) {
1042 cutting_skill = BIO_CQB_LEVEL;
1043 }
1044
1045 if( weap.is_unarmed_weapon() ) {
1046 // TODO: 1-handed weapons that aren't unarmed attacks
1047 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
1048 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
1049 weap.is_null();
1050 if( left_empty || right_empty ) {
1051 float per_hand = 0.0f;
1052 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
1053 per_hand += 2;
1054 }
1055
1056 for( const trait_id &mut : get_mutations() ) {
1057 if( mut->flags.count( "NEED_ACTIVE_TO_MELEE" ) > 0 && !has_active_mutation( mut ) ) {
1058 continue;
1059 }
1060 float unarmed_bonus = 0.0f;
1061 const int cut_bonus = mut->cut_dmg_bonus;
1062 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && cut_bonus > 0 ) {
1063 unarmed_bonus += std::min( get_skill_level( skill_unarmed ) / 2, 4 );
1064 }
1065 per_hand += cut_bonus + unarmed_bonus;
1066 const std::pair<int, int> rand_cut = mut->rand_cut_bonus;
1067 per_hand += average ? ( rand_cut.first + rand_cut.second ) / 2.0f : rng( rand_cut.first,
1068 rand_cut.second );
1069 }
1070 // TODO: add acidproof check back to slime hands (probably move it elsewhere)
1071
1072 cut_dam += per_hand; // First hand
1073 if( left_empty && right_empty ) {
1074 // Second hand
1075 cut_dam += per_hand;
1076 }
1077 }
1078 }
1079
1080 if( cut_dam <= 0.0f ) {
1081 return; // No negative damage!
1082 }
1083
1084 int arpen = 0;
1085 float armor_mult = 1.0f;
1086
1087 // 80%, 88%, 96%, 104%, 112%, 116%, 120%, 124%, 128%, 132%
1088 /** @EFFECT_CUTTING increases cutting damage multiplier */
1089 if( cutting_skill < 5 ) {
1090 cut_mul *= 0.8 + 0.08 * cutting_skill;
1091 } else {
1092 cut_mul *= 0.96 + 0.04 * cutting_skill;
1093 }
1094
1095 arpen += mabuff_arpen_bonus( DT_CUT );
1096
1097 cut_mul *= mabuff_damage_mult( DT_CUT );
1098 if( crit ) {
1099 cut_mul *= 1.25f;
1100 arpen += 5;
1101 armor_mult = 0.75f; //25% armor penetration
1102 }
1103
1104 di.add_damage( DT_CUT, cut_dam, arpen, armor_mult, cut_mul );
1105}
static const skill_id skill_cutting("cutting")

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_CUT, get_mutations(), get_skill_level(), has_active_bionic(), has_active_mutation(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), rng(), skill_cutting, and skill_unarmed.

Referenced by roll_all_damage().

◆ roll_stab_damage()

void Character::roll_stab_damage ( bool  crit,
damage_instance di,
bool  average,
const item weap 
) const

Adds player's total stab damage to the damage instance.

Stabbing increases stabbing damage multiplier

Definition at line 1107 of file melee.cpp.

1109{
1110 float stab_dam = mabuff_damage_bonus( DT_STAB ) + weap.damage_melee( DT_STAB );
1111
1112 int unarmed_skill = get_skill_level( skill_unarmed );
1113 int stabbing_skill = get_skill_level( skill_stabbing );
1114
1115 if( has_active_bionic( bio_cqb ) ) {
1116 stabbing_skill = BIO_CQB_LEVEL;
1117 }
1118
1119 if( weap.is_unarmed_weapon() ) {
1120 const bool left_empty = !natural_attack_restricted_on( bodypart_id( "hand_l" ) );
1121 const bool right_empty = !natural_attack_restricted_on( bodypart_id( "hand_r" ) ) &&
1122 weap.is_null();
1123 if( left_empty || right_empty ) {
1124 float per_hand = 0.0f;
1125
1126 for( const trait_id &mut : get_mutations() ) {
1127 int stab_bonus = mut->pierce_dmg_bonus;
1128 int unarmed_bonus = 0;
1129 if( mut->flags.count( "UNARMED_BONUS" ) > 0 && stab_bonus > 0 ) {
1130 unarmed_bonus = std::min( unarmed_skill / 2, 4 );
1131 }
1132
1133 per_hand += stab_bonus + unarmed_bonus;
1134 }
1135
1136 if( has_bionic( bionic_id( "bio_razors" ) ) ) {
1137 per_hand += 2;
1138 }
1139
1140 stab_dam += per_hand; // First hand
1141 if( left_empty && right_empty ) {
1142 // Second hand
1143 stab_dam += per_hand;
1144 }
1145 }
1146 }
1147
1148 if( stab_dam <= 0 ) {
1149 return; // No negative stabbing!
1150 }
1151
1152 float stab_mul = 1.0f;
1153 // 66%, 76%, 86%, 96%, 106%, 116%, 122%, 128%, 134%, 140%
1154 /** @EFFECT_STABBING increases stabbing damage multiplier */
1155 if( stabbing_skill <= 5 ) {
1156 stab_mul = 0.66 + 0.1 * stabbing_skill;
1157 } else {
1158 stab_mul = 0.86 + 0.06 * stabbing_skill;
1159 }
1160 int arpen = mabuff_arpen_bonus( DT_STAB );
1161 stab_mul *= mabuff_damage_mult( DT_STAB );
1162 float armor_mult = 1.0f;
1163
1164 if( crit ) {
1165 // Critical damage bonus for stabbing scales with skill
1166 stab_mul *= 1.0 + ( stabbing_skill / 10.0 );
1167 // Stab criticals have extra %arpen
1168 armor_mult = 0.66f;
1169 }
1170
1171 di.add_damage( DT_STAB, stab_dam, arpen, armor_mult, stab_mul );
1172}

References damage_instance::add_damage(), bio_cqb, BIO_CQB_LEVEL, bionic_id, item::damage_melee(), DT_STAB, get_mutations(), get_skill_level(), has_active_bionic(), has_bionic(), item::is_null(), item::is_unarmed_weapon(), mabuff_arpen_bonus(), mabuff_damage_bonus(), mabuff_damage_mult(), natural_attack_restricted_on(), skill_stabbing, and skill_unarmed.

Referenced by roll_all_damage().

◆ rooted()

void Character::rooted ( )

Definition at line 8849 of file character.cpp.

8851{
8852 double shoe_factor = footwear_factor();
8853 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8854 get_map().has_flag( flag_PLOWABLE, pos() ) && shoe_factor != 1.0 ) {
8855 if( one_in( 96 ) ) {
8856 vitamin_mod( vitamin_id( "iron" ), 1, true );
8857 vitamin_mod( vitamin_id( "calcium" ), 1, true );
8858 }
8859 if( get_thirst() <= thirst_levels::turgid && x_in_y( 75, 425 ) ) {
8860 mod_thirst( -1 );
8861 }
8862 mod_healthy_mod( 5, 50 );
8863 }
8864}
static const std::string flag_PLOWABLE("PLOWABLE")
int vitamin_mod(const vitamin_id &vit, int qty, bool capped=true)
Add or subtract vitamins from character storage pools.
string_id< vitamin > vitamin_id
Definition: type_id.h:190

References flag_PLOWABLE(), footwear_factor(), get_map(), get_thirst(), Creature::has_flag(), has_trait(), mod_healthy_mod(), mod_thirst(), one_in(), pos(), trait_ROOTS2, trait_ROOTS3, turgid, vitamin_mod(), and x_in_y().

Referenced by player_activity::do_turn().

◆ rooted_message()

void Character::rooted_message ( ) const

Handles rooting effects.

Definition at line 8839 of file character.cpp.

8840{
8841 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
8842 if( ( has_trait( trait_ROOTS2 ) || has_trait( trait_ROOTS3 ) ) &&
8844 !wearing_shoes ) {
8845 add_msg( m_info, _( "You sink your roots into the soil." ) );
8846 }
8847}

References _, add_msg(), flag_PLOWABLE(), get_map(), Creature::has_flag(), has_trait(), is_wearing_shoes(), LEFT, m_info, pos(), RIGHT, trait_ROOTS2, and trait_ROOTS3.

Referenced by player_activity::start_or_resume().

◆ run_cost()

int Character::run_cost ( int  base_cost,
bool  diag = false 
) const

Returns the player's modified base movement cost.

Definition at line 10031 of file character.cpp.

10032{
10033 float movecost = static_cast<float>( base_cost );
10034 if( diag ) {
10035 movecost *= 0.7071f; // because everything here assumes 100 is base
10036 }
10037 const bool flatground = movecost < 105;
10038 map &here = get_map();
10039 // The "FLAT" tag includes soft surfaces, so not a good fit.
10040 const bool on_road = flatground && here.has_flag( "ROAD", pos() );
10041 const bool on_fungus = here.has_flag_ter_or_furn( "FUNGUS", pos() );
10042
10043 if( !is_mounted() ) {
10044 if( movecost > 100 ) {
10045 movecost *= mutation_value( "movecost_obstacle_modifier" );
10046 if( movecost < 100 ) {
10047 movecost = 100;
10048 }
10049 }
10050 if( has_trait( trait_M_IMMUNE ) && on_fungus ) {
10051 if( movecost > 75 ) {
10052 // Mycal characters are faster on their home territory, even through things like shrubs
10053 movecost = 75;
10054 }
10055 }
10056
10057 // Linearly increase move cost relative to individual leg hp.
10058 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_l" ) ) ) /
10059 static_cast<float>( get_part_hp_max( bodypart_id( "leg_l" ) ) ) );
10060 movecost += 50 * ( 1 - static_cast<float>( get_part_hp_cur( bodypart_id( "leg_r" ) ) ) /
10061 static_cast<float>( get_part_hp_max( bodypart_id( "leg_r" ) ) ) );
10062 movecost *= mutation_value( "movecost_modifier" );
10063 if( flatground ) {
10064 movecost *= mutation_value( "movecost_flatground_modifier" );
10065 }
10067 movecost *= .9f;
10068 }
10070 movecost *= ( move_mode == CMM_RUN ? 0.75f : 0.9f );
10071 } else if( has_bionic( bio_jointservo ) ) {
10072 movecost *= 0.95f;
10073 }
10074
10075 if( worn_with_flag( "SLOWS_MOVEMENT" ) ) {
10076 movecost *= 1.1f;
10077 }
10078 if( worn_with_flag( "FIN" ) ) {
10079 movecost *= 1.5f;
10080 }
10081 if( worn_with_flag( "ROLLER_INLINE" ) ) {
10082 if( on_road ) {
10083 movecost *= 0.5f;
10084 } else {
10085 movecost *= 1.5f;
10086 }
10087 }
10088 // Quad skates might be more stable than inlines,
10089 // but that also translates into a slower speed when on good surfaces.
10090 if( worn_with_flag( "ROLLER_QUAD" ) ) {
10091 if( on_road ) {
10092 movecost *= 0.7f;
10093 } else {
10094 movecost *= 1.3f;
10095 }
10096 }
10097 // Skates with only one wheel (roller shoes) are fairly less stable
10098 // and fairly slower as well
10099 if( worn_with_flag( "ROLLER_ONE" ) ) {
10100 if( on_road ) {
10101 movecost *= 0.85f;
10102 } else {
10103 movecost *= 1.1f;
10104 }
10105 }
10106
10107 movecost +=
10108 ( ( encumb( bp_foot_l ) + encumb( bp_foot_r ) ) * 2.5 +
10109 ( encumb( bp_leg_l ) + encumb( bp_leg_r ) ) * 1.5 ) / 10;
10110
10111 // ROOTS3 does slow you down as your roots are probing around for nutrients,
10112 // whether you want them to or not. ROOTS1 is just too squiggly without shoes
10113 // to give you some stability. Plants are a bit of a slow-mover. Deal.
10114 if( has_trait( trait_ROOTS3 ) && here.has_flag( "DIGGABLE", pos() ) ) {
10115 movecost += 10 * footwear_factor();
10116 }
10117
10119 movecost /= stamina_move_cost_modifier();
10120
10121 if( movecost < 20.0 ) {
10122 movecost = 20.0;
10123 }
10124 }
10125
10126 if( diag ) {
10127 movecost *= M_SQRT2;
10128 }
10129
10130 return static_cast<int>( movecost );
10131}
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_PADDED_FEET("PADDED_FEET")
static const bionic_id bio_jointservo("bio_jointservo")
#define M_SQRT2
Definition: math_defines.h:29

References bio_jointservo, bonus_from_enchantments(), bp_foot_l, bp_foot_r, bp_leg_l, bp_leg_r, CMM_RUN, encumb(), footwear_factor(), get_map(), Creature::get_part_hp_cur(), Creature::get_part_hp_max(), has_active_bionic(), has_bionic(), has_trait(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), is_mounted(), M_SQRT2, enchant_vals::MOVE_COST, move_mode, mutation_value(), pos(), stamina_move_cost_modifier(), trait_M_IMMUNE, trait_PADDED_FEET, trait_ROOTS3, and worn_with_flag().

Referenced by draw_speed_tab(), npc::move_to(), speed_description(), speed_rating(), npc::speed_rating(), and game::walk_move().

◆ rust_rate()

int Character::rust_rate ( ) const

Returns the player's skill rust rate.

Intelligence reduces skill rust by 10% per level above 8

Definition at line 3394 of file character.cpp.

3395{
3396 const std::string &rate_option = get_option<std::string>( "SKILL_RUST" );
3397 if( rate_option == "off" ) {
3398 return 0;
3399 }
3400
3401 // Stat window shows stat effects on based on current stat
3402 int intel = get_int();
3403 /** @EFFECT_INT reduces skill rust by 10% per level above 8 */
3404 int ret = ( ( rate_option == "vanilla" || rate_option == "capped" ) ?
3405 100 : 100 + 10 * ( intel - 8 ) );
3406
3407 ret *= mutation_value( "skill_rust_multiplier" );
3408
3409 if( ret < 0 ) {
3410 ret = 0;
3411 }
3412
3413 return ret;
3414}

References get_int(), mutation_value(), and cata::hash64_detail::ret.

Referenced by do_skill_rust(), draw_stats_info(), and set_stats().

◆ scored_crit()

bool Character::scored_crit ( float  target_dodge,
const item weap 
) const

Returns true if the player scores a critical hit.

Definition at line 783 of file melee.cpp.

784{
785 return rng_float( 0, 1.0 ) < crit_chance( hit_roll(), target_dodge, weap );
786}
double crit_chance(float roll_hit, float target_dodge, const item &weap) const
Returns the chance to critical given a hit roll and target's dodge roll.
Definition: melee.cpp:796

References crit_chance(), hit_roll(), and rng_float().

Referenced by melee_attack().

◆ sees() [1/2]

bool Character::sees ( const Creature critter) const
overridevirtual

The functions check whether this creature can see the target.

The target may either be another creature (critter), or a specific point on the map.

The function that take another creature as input should check visibility of that creature (e.g. not digging, or otherwise invisible). They must than check whether the location of the other monster is visible.

Reimplemented from Creature.

Definition at line 10456 of file character.cpp.

10457{
10458 // This handles only the player/npc specific stuff (monsters don't have traits or bionics).
10459 const int dist = rl_dist( pos(), critter.pos() );
10460 if( dist <= 3 && has_active_mutation( trait_ANTENNAE ) ) {
10461 return true;
10462 }
10463
10464 return Creature::sees( critter );
10465}
virtual bool sees(const Creature &critter) const
The functions check whether this creature can see the target.
Definition: creature.cpp:205

References has_active_mutation(), Creature::pos(), pos(), rl_dist(), Creature::sees(), and trait_ANTENNAE.

◆ sees() [2/2]

bool Character::sees ( const tripoint t,
bool  is_player = false,
int  range_mod = 0 
) const
overridevirtual

Reimplemented from Creature.

Definition at line 10439 of file character.cpp.

10440{
10441 const int wanted_range = rl_dist( pos(), t );
10442 bool can_see = is_player() ? get_map().pl_sees( t, wanted_range ) :
10443 Creature::sees( t );
10444 // Clairvoyance is now pretty cheap, so we can check it early
10445 if( wanted_range < MAX_CLAIRVOYANCE && wanted_range < clairvoyance() ) {
10446 return true;
10447 }
10448
10449 if( can_see && wanted_range > unimpaired_range() ) {
10450 can_see = false;
10451 }
10452
10453 return can_see;
10454}
int unimpaired_range() const
Returns the player maximum vision range factoring in mutations, diseases, and other effects.
Definition: character.cpp:630
int clairvoyance() const
Returns the distance the player can see through walls.
Definition: character.cpp:689
bool pl_sees(const tripoint &t, int max_range) const
Whether the player character (g->u) can see the given square (local map coordinates).
Definition: lightmap.cpp:813

References clairvoyance(), get_map(), Creature::is_player(), map::pl_sees(), pos(), rl_dist(), Creature::sees(), and unimpaired_range().

Referenced by activate_bionic(), npc::address_needs(), npc::address_player(), grid_furn_transform_queue::apply(), npc::assess_danger(), bionics_uninstall_failure(), calculate_aim_cap(), game::catch_a_monster(), game::chat(), check_mount_is_spooked(), check_mount_will_move(), npc::complain(), npc::do_reload(), draw_critter_internal(), game::draw_line(), game::draw_look_around_cursor(), draw_throw_aim(), npc::drop_items(), explosion_handler::emp_blast(), npc::enough_time_to_reload(), npc::execute_action(), game::extended_description(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), heal_actor::finish_using(), game::fling_creature(), npc::follow_distance(), game::forced_door_closing(), fungal_effects::fungalize(), generic_multi_activity_check_requirement(), get_hostile_creatures(), get_path_avoid(), game::get_player_input(), get_visible_creatures(), game::handle_action(), npc::handle_sound(), vehicle::handle_trap(), npc::heal_player(), npc::heal_self(), talk_function::hostile(), is_visible_in_range(), mdeath::jabberwock(), game::knockback(), target_ui::list_friendlies_in_lof(), game::list_items(), game::look_around(), npc::method_of_attack(), npc::move(), npc::mug_player(), iuse::note_bionics(), target_ui::panel_target_info(), npc::pick_up_item(), pl_sees(), npc::pretend_fire(), npc::pretend_heal(), game::print_creature_info(), npc::print_info(), sounds::process_sound_markers(), npc::reach_omt_destination(), npc::regen_ai_cache(), iuse::robotcontrol(), character_funcs::search_surroundings(), npc::see_item_say_smth(), activity_handlers::spellcasting_finish(), fungal_effects::spread_fungus_one_tile(), suffer_from_schizophrenia(), game::try_get_right_click_action(), character_funcs::try_uncanny_dodge(), game::update_stair_monsters(), editmap::update_view_with_help(), countdown_actor::use(), npc::use_painkiller(), and npc::wield_better_weapon().

◆ sees_with_infrared()

bool Character::sees_with_infrared ( const Creature critter) const

Check whether the this player can see the other creature with infrared.

This implies this player can see infrared and the target is visible with infrared (is warm). And of course a line of sight exists.

Definition at line 10212 of file character.cpp.

10213{
10214 if( !vision_mode_cache[IR_VISION] || !critter.is_warm() ) {
10215 return false;
10216 }
10217
10218 map &here = get_map();
10219 if( is_player() || critter.is_player() ) {
10220 // Players should not use map::sees
10221 // Likewise, players should not be "looked at" with map::sees, not to break symmetry
10222 return here.pl_line_of_sight( critter.pos(),
10224 }
10225
10226 return here.sees( pos(), critter.pos(), sight_range( current_daylight_level( calendar::turn ) ) );
10227}
double current_daylight_level(const time_point &p)
Returns the current seasonally-adjusted maximum daylight level.
Definition: calendar.cpp:171

References current_daylight_level(), get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), IR_VISION, Creature::is_player(), Creature::is_warm(), Creature::pos(), pos(), sight_range(), calendar::turn, and vision_mode_cache.

Referenced by calculate_aim_cap(), draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ sees_with_specials()

bool Character::sees_with_specials ( const Creature critter) const

Definition at line 6364 of file character.cpp.

6365{
6366 // electroreceptors grants vision of robots and electric monsters through walls
6368 ( critter.in_species( ROBOT ) || critter.has_flag( MF_ELECTRIC ) ) ) {
6369 return true;
6370 }
6371
6372 if( critter.digging() && has_active_bionic( bio_ground_sonar ) ) {
6373 // Bypass the check below, the bionic sonar also bypasses the sees(point) check because
6374 // walls don't block sonar which is transmitted in the ground, not the air.
6375 // TODO: this might need checks whether the player is in the air, or otherwise not connected
6376 // to the ground. It also might need a range check.
6377 return true;
6378 }
6379
6380 return false;
6381}
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const species_id ROBOT("ROBOT")
static const bionic_id bio_ground_sonar("bio_ground_sonar")
virtual bool digging() const
Definition: creature.cpp:182
@ MF_ELECTRIC
Definition: mtype.h:95

References bio_ground_sonar, Creature::digging(), has_active_bionic(), Creature::has_flag(), has_trait(), Creature::in_species(), MF_ELECTRIC, ROBOT, and trait_ELECTRORECEPTORS.

Referenced by draw_critter_internal(), target_ui::panel_target_info(), pl_sees(), and game::print_all_tile_info().

◆ set_base_age()

void Character::set_base_age ( int  age)

Definition at line 6790 of file character.cpp.

6791{
6792 init_age = age;
6793}

References age(), and init_age.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_base_height()

void Character::set_base_height ( int  height)

Definition at line 6819 of file character.cpp.

6820{
6822}

References height(), and init_height.

Referenced by debug_menu::character_edit_menu(), and set_description().

◆ set_check_encumbrance()

void Character::set_check_encumbrance ( bool  new_check)
inline

Definition at line 2021 of file character.h.

2021 {
2022 check_encumbrance = new_check;
2023 }

References check_encumbrance.

◆ set_destination()

void Character::set_destination ( const std::vector< tripoint > &  route,
const player_activity new_destination_activity = player_activity() 
)

◆ set_destination_activity()

void Character::set_destination_activity ( const player_activity new_destination_activity)

Definition at line 953 of file character.cpp.

954{
955 destination_activity = new_destination_activity;
956}

References destination_activity.

Referenced by set_destination().

◆ set_dex_bonus()

void Character::set_dex_bonus ( int  ndex)
virtual

Definition at line 4184 of file character.cpp.

4185{
4186 dex_bonus = ndex;
4187 dex_cur = std::max( 0, dex_max + dex_bonus );
4188}

References dex_bonus, dex_cur, and dex_max.

◆ set_fac_id()

void Character::set_fac_id ( const std::string &  my_fac_id)

Definition at line 7756 of file character.cpp.

7757{
7758 fac_id = faction_id( my_fac_id );
7759}
faction_id fac_id
Definition: character.h:2199
string_id< faction > faction_id
Definition: clzones.h:30

References fac_id.

Referenced by npc_template::load().

◆ set_fatigue()

void Character::set_fatigue ( int  nfatigue)
virtual

Definition at line 4465 of file character.cpp.

4466{
4467 nfatigue = std::max( nfatigue, 0 );
4468 if( fatigue != nfatigue ) {
4469 fatigue = nfatigue;
4470 on_stat_change( "fatigue", fatigue );
4471 }
4472}

References fatigue, and on_stat_change().

Referenced by npc::address_needs(), debug_menu::character_edit_menu(), check_needs_extremes(), environmental_revert_effect(), basecamp::finish_return(), hardcoded_effects(), mod_fatigue(), and update_needs().

◆ set_healthy()

void Character::set_healthy ( int  nhealthy)
virtual

Setters for health values exclusive to characters.

Definition at line 4267 of file character.cpp.

4268{
4269 healthy = nhealthy;
4270}

References healthy.

Referenced by debug_menu::character_edit_menu(), and environmental_revert_effect().

◆ set_healthy_mod()

void Character::set_healthy_mod ( int  nhealthy_mod)
virtual

Definition at line 4279 of file character.cpp.

4280{
4281 healthy_mod = nhealthy_mod;
4282}

References healthy_mod.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), suffer_from_radiation(), update_health(), and vomit().

◆ set_highest_cat_level()

void Character::set_highest_cat_level ( )

Recalculates mutation_category_level[] values for the player.

Definition at line 7800 of file character.cpp.

7801{
7803
7804 // For each of our mutations...
7805 for( const trait_id &mut : get_mutations() ) {
7806 // ...build up a map of all prerequisite/replacement mutations along the tree, along with their distance from the current mutation
7807 std::unordered_map<trait_id, int> dependency_map;
7808 build_mut_dependency_map( mut, dependency_map, 0 );
7809
7810 // Then use the map to set the category levels
7811 for( const std::pair<const trait_id, int> &i : dependency_map ) {
7812 const mutation_branch &mdata = i.first.obj();
7813 if( !mdata.flags.count( "NON_THRESH" ) ) {
7814 for( const std::string &cat : mdata.category ) {
7815 // Decay category strength based on how far it is from the current mutation
7816 mutation_category_level[cat] += 8 / static_cast<int>( std::pow( 2, i.second ) );
7817 }
7818 }
7819 }
7820 }
7821}

References build_mut_dependency_map(), mutation_branch::category, mutation_branch::flags, get_mutations(), and mutation_category_level.

Referenced by avatar::load(), mutate_towards(), remove_mutation(), and game::start_game().

◆ set_int_bonus()

void Character::set_int_bonus ( int  nint)
virtual

Definition at line 4194 of file character.cpp.

4195{
4196 int_bonus = nint;
4197 int_cur = std::max( 0, int_max + int_bonus );
4198}

References int_bonus, int_cur, and int_max.

◆ set_max_power_level()

void Character::set_max_power_level ( const units::energy npower_max)

Definition at line 1920 of file character.cpp.

1921{
1922 max_power_level = npower_max;
1923}

References max_power_level.

Referenced by bionics_install_failure(), and player::player().

◆ set_movement_mode()

virtual void Character::set_movement_mode ( character_movemode  mode)
pure virtual

Implemented in avatar, and npc.

Referenced by dismount().

◆ set_mutation()

◆ set_npc_ai_info_cache()

void Character::set_npc_ai_info_cache ( npc_ai_info  key,
double  val 
) const

Definition at line 10639 of file character.cpp.

10640{
10641 npc_ai_info_cache[key] = val;
10642}

References npc_ai_info_cache.

Referenced by npc::check_or_reload_cbm(), npc::find_reloadable(), npc::wield_better_weapon(), and npc_ai::wielded_value().

◆ set_pain()

void Character::set_pain ( int  npain)
overridevirtual

Sets new intensity of pain an reacts to it.

Reimplemented from Creature.

Definition at line 791 of file character.cpp.

792{
793 const int prev_pain = get_perceived_pain();
794 Creature::set_pain( npain );
795 const int cur_pain = get_perceived_pain();
796
797 if( cur_pain != prev_pain ) {
798 react_to_felt_pain( cur_pain - prev_pain );
799 on_stat_change( "perceived_pain", cur_pain );
800 }
801}
void react_to_felt_pain(int intensity)
Definition: character.cpp:740
virtual void set_pain(int npain)
Definition: creature.cpp:1398

References get_perceived_pain(), on_stat_change(), react_to_felt_pain(), and Creature::set_pain().

Referenced by environmental_revert_effect(), game::is_game_over(), and suffer_from_other_mutations().

◆ set_painkiller()

void Character::set_painkiller ( int  npkill)

Sets intensity of painkillers

Definition at line 9798 of file character.cpp.

9799{
9800 npkill = std::max( npkill, 0 );
9801 if( pkill != npkill ) {
9802 const int prev_pain = get_perceived_pain();
9803 pkill = npkill;
9804 on_stat_change( "pkill", pkill );
9805 const int cur_pain = get_perceived_pain();
9806
9807 if( cur_pain != prev_pain ) {
9808 react_to_felt_pain( cur_pain - prev_pain );
9809 on_stat_change( "perceived_pain", cur_pain );
9810 }
9811 }
9812}

References get_perceived_pain(), on_stat_change(), pkill, and react_to_felt_pain().

Referenced by activate_bionic(), environmental_revert_effect(), mod_painkiller(), iuse::smoking(), and iuse::weed_cake().

◆ set_per_bonus()

void Character::set_per_bonus ( int  nper)
virtual

Definition at line 4189 of file character.cpp.

4190{
4191 per_bonus = nper;
4192 per_cur = std::max( 0, per_max + per_bonus );
4193}

References per_bonus, per_cur, and per_max.

◆ set_power_level()

void Character::set_power_level ( const units::energy npower)

Definition at line 1915 of file character.cpp.

1916{
1917 power_level = std::min( npower, max_power_level );
1918}

References max_power_level, and power_level.

Referenced by activate_bionic(), avatar::create(), mod_power_level(), and player::player().

◆ set_primary_weapon()

void Character::set_primary_weapon ( const item new_weapon)

Use this when primary weapon might not exist yet.

Definition at line 172 of file melee.cpp.

173{
174 auto &body = get_body();
175 auto iter = body.find( body_part_arm_r );
176 if( iter != body.end() ) {
178 if( part.wielding.wielded == nullptr ) {
179 part.wielding.wielded = std::make_shared<item>( new_weapon );
180 } else {
181 *part.wielding.wielded = new_weapon;
182 }
183 }
184}

References Creature::body, body_part_arm_r, Creature::get_body(), Creature::get_part(), wield_status::wielded, and bodypart::wielding.

Referenced by activate_bionic(), debug_menu::character_edit_menu(), avatar::create(), deactivate_bionic(), mattack::frag(), i_rem(), load(), character_funcs::normalize(), npc::randomize(), remove_weapon(), mattack::rifle(), gun_actor::shoot(), spell_effect::spawn_ethereal_item(), npc::starting_weapon(), mattack::tankgun(), character_funcs::try_wield_contents(), npc::wield(), and avatar::wield().

◆ set_rad()

void Character::set_rad ( int  new_rad)

◆ set_skill_level()

◆ set_sleep_deprivation()

void Character::set_sleep_deprivation ( int  nsleep_deprivation)
virtual

Definition at line 4474 of file character.cpp.

4475{
4476 sleep_deprivation = std::min( static_cast< int >( sleep_deprivation_levels::massive ), std::max( 0,
4477 nsleep_deprivation ) );
4478}

References massive, and sleep_deprivation.

Referenced by debug_menu::character_edit_menu(), environmental_revert_effect(), basecamp::finish_return(), mod_sleep_deprivation(), and update_needs().

◆ set_stamina()

◆ set_stashed_activity()

void Character::set_stashed_activity ( const player_activity act,
const player_activity act_back = player_activity() 
)

Definition at line 913 of file character.cpp.

914{
916 stashed_outbounds_backlog = act_back;
917}

References act, stashed_outbounds_activity, and stashed_outbounds_backlog.

◆ set_stim()

void Character::set_stim ( int  new_stim)

Definition at line 7065 of file character.cpp.

7066{
7067 stim = new_stim;
7068}

References stim.

Referenced by activate_bionic(), environmental_revert_effect(), modify_stimulation(), and update_needs().

◆ set_stored_kcal()

void Character::set_stored_kcal ( int  kcal)
virtual

Setters for need values exclusive to characters.

Definition at line 4335 of file character.cpp.

4336{
4337 if( stored_calories != kcal ) {
4338 stored_calories = std::min( kcal, max_stored_kcal() );
4339 }
4340}

References max_stored_kcal(), and stored_calories.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), avatar::create(), environmental_revert_effect(), marloss_common(), mod_stored_kcal(), and update_stomach().

◆ set_str_bonus()

void Character::set_str_bonus ( int  nstr)
virtual

Setters for stats exclusive to characters.

Definition at line 4179 of file character.cpp.

4180{
4181 str_bonus = nstr;
4182 str_cur = std::max( 0, str_max + str_bonus );
4183}

References str_bonus, str_cur, and str_max.

◆ set_thirst()

void Character::set_thirst ( int  nthirst)
virtual

Definition at line 4447 of file character.cpp.

4448{
4449 if( thirst != nthirst ) {
4450 thirst = nthirst;
4451 on_stat_change( "thirst", thirst );
4452 }
4453}

References on_stat_change(), and thirst.

Referenced by debug_menu::character_edit_menu(), npc::consume_food(), npc::consume_food_from_camp(), environmental_revert_effect(), basecamp::finish_return(), mod_thirst(), update_stomach(), and vomit().

◆ set_time_died()

void Character::set_time_died ( const time_point time)
inline

set the turn the turn the character died if not already done

Definition at line 1477 of file character.h.

1477 {
1479 time_died = time;
1480 }
1481 }
@ time
Recharges slowly with time.

References calendar::before_time_starts, time, and time_died.

Referenced by die().

◆ set_type_of_scent()

void Character::set_type_of_scent ( const scenttype_id id)

Definition at line 8761 of file character.cpp.

8762{
8763 type_of_scent = id;
8764}

References id, and type_of_scent.

Referenced by restore_scent(), update_type_of_scent(), and change_scent_iuse::use().

◆ set_underwater()

void Character::set_underwater ( bool  x)
overridevirtual

Reimplemented from Creature.

Definition at line 10626 of file character.cpp.

10627{
10628 if( is_underwater() != x ) {
10631 }
10632}
virtual void set_underwater(bool x)
Definition: creature.cpp:177

References Creature::is_underwater(), recalc_sight_limits(), and Creature::set_underwater().

Referenced by avatar_action::swim(), game::vertical_move(), and game::walk_move().

◆ setID()

void Character::setID ( character_id  i,
bool  force = false 
)

Definition at line 483 of file character.cpp.

484{
485 if( id.is_valid() && !force ) {
486 debugmsg( "tried to set id of a npc/player, but has already a id: %d", id.get_value() );
487 } else if( !i.is_valid() && !force ) {
488 debugmsg( "tried to set invalid id of a npc/player: %d", i.get_value() );
489 } else {
490 id = i;
491 }
492}
bool is_valid() const
Definition: character_id.h:19
int get_value() const
Definition: character_id.h:23

References debugmsg, character_id::get_value(), Creature::get_value(), and character_id::is_valid().

Referenced by player::load(), game::load(), npc::randomize(), game::start_game(), and main_menu::world_tab().

◆ setpos()

◆ setx()

void Character::setx ( int  x)
inline

◆ sety()

void Character::sety ( int  y)
inline

◆ setz()

void Character::setz ( int  z)
inline

Definition at line 810 of file character.h.

810 {
811 setpos( tripoint( position.xy(), z ) );
812 }

References position, setpos(), and tripoint::xy().

Referenced by start_location::place_player(), and game::vertical_shift().

◆ shift_destination()

void Character::shift_destination ( point  shift)

Definition at line 10365 of file character.cpp.

10366{
10368 *next_expected_position += shift;
10369 }
10370
10371 for( auto &elem : auto_move_route ) {
10372 elem += shift;
10373 }
10374}

References auto_move_route, and next_expected_position.

Referenced by game::update_map().

◆ shoe_type_count()

int Character::shoe_type_count ( const itype_id it) const

Returns 1 if the player is wearing an item of that count on one foot, 2 if on both, and zero if on neither.

Definition at line 8954 of file character.cpp.

8955{
8956 int ret = 0;
8957 if( is_wearing_on_bp( it, bodypart_id( "foot_l" ) ) ) {
8958 ret++;
8959 }
8960 if( is_wearing_on_bp( it, bodypart_id( "foot_r" ) ) ) {
8961 ret++;
8962 }
8963 return ret;
8964}
bool is_wearing_on_bp(const itype_id &it, const bodypart_id &bp) const
Returns true if the player is wearing the item on the given body part.
Definition: character.cpp:3255

References is_wearing_on_bp(), and cata::hash64_detail::ret.

Referenced by avatar_action::swim(), and game::vertical_move().

◆ short_description()

std::string Character::short_description ( ) const

Definition at line 10354 of file character.cpp.

10355{
10356 return join( short_description_parts(), "; " );
10357}
std::vector< std::string > short_description_parts() const
arg_join< It, Sentinel, char > join(It begin, Sentinel end, string_view sep)
Returns an object that formats the iterator range [begin, end) with elements separated by sep.

References join(), and short_description_parts().

◆ short_description_parts()

std::vector< std::string > Character::short_description_parts ( ) const

Definition at line 10330 of file character.cpp.

10331{
10332 std::vector<std::string> result;
10333
10334 std::string gender = male ? _( "Male" ) : _( "Female" );
10335 result.push_back( name + ", " + gender );
10336 if( is_armed() ) {
10337 result.push_back( _( "Wielding: " ) + primary_weapon().tname() );
10338 }
10339 const std::string worn_str = enumerate_as_string( worn.begin(), worn.end(),
10340 []( const item & it ) {
10341 return it.tname();
10342 } );
10343 if( !worn_str.empty() ) {
10344 result.push_back( _( "Wearing: " ) + worn_str );
10345 }
10346 const int visibility_cap = 0; // no cap
10347 const auto trait_str = visible_mutations( visibility_cap );
10348 if( !trait_str.empty() ) {
10349 result.push_back( _( "Traits: " ) + trait_str );
10350 }
10351 return result;
10352}
std::string visible_mutations(int visibility_cap) const
Returns an enumeration of visible mutations with colors.
Definition: mutation.cpp:1728

References _, enumerate_as_string(), is_armed(), male, name, primary_weapon(), visible_mutations(), and worn.

Referenced by short_description().

◆ shout()

void Character::shout ( std::string  msg = "",
bool  order = false 
)

Definition at line 7639 of file character.cpp.

7640{
7641 int base = 10;
7642 std::string shout;
7643
7644 // You can't shout without your face
7645 if( has_trait( trait_PROF_FOODP ) && !( is_wearing( itype_id( "foodperson_mask" ) ) ||
7646 is_wearing( itype_id( "foodperson_mask_on" ) ) ) ) {
7647 add_msg_if_player( m_warning, _( "You try to shout but you have no face!" ) );
7648 return;
7649 }
7650
7651 // Mutations make shouting louder, they also define the default message
7652 if( has_trait( trait_SHOUT3 ) ) {
7653 base = 20;
7654 if( msg.empty() ) {
7655 msg = is_player() ? _( "yourself let out a piercing howl!" ) : _( "a piercing howl!" );
7656 shout = "howl";
7657 }
7658 } else if( has_trait( trait_SHOUT2 ) ) {
7659 base = 15;
7660 if( msg.empty() ) {
7661 msg = is_player() ? _( "yourself scream loudly!" ) : _( "a loud scream!" );
7662 shout = "scream";
7663 }
7664 }
7665
7666 if( msg.empty() ) {
7667 msg = is_player() ? _( "yourself shout loudly!" ) : _( "a loud shout!" );
7668 shout = "default";
7669 }
7670 int noise = get_shout_volume();
7671
7672 // Minimum noise volume possible after all reductions.
7673 // Volume 1 can't be heard even by player
7674 constexpr int minimum_noise = 2;
7675
7676 if( noise <= base ) {
7677 std::string dampened_shout;
7678 std::transform( msg.begin(), msg.end(), std::back_inserter( dampened_shout ), tolower );
7679 msg = std::move( dampened_shout );
7680 }
7681
7682 // Screaming underwater is not good for oxygen and harder to do overall
7683 if( is_underwater() ) {
7685 mod_stat( "oxygen", -noise );
7686 }
7687 }
7688
7689 const int penalty = encumb( bp_mouth ) * 3 / 2;
7690 // TODO: indistinct noise descriptions should be handled in the sounds code
7691 if( noise <= minimum_noise ) {
7693 _( "The sound of your voice is almost completely muffled!" ) );
7694 msg = is_player() ? _( "your muffled shout" ) : _( "an indistinct voice" );
7695 } else if( noise * 2 <= noise + penalty ) {
7696 // The shout's volume is 1/2 or lower of what it would be without the penalty
7697 add_msg_if_player( m_warning, _( "The sound of your voice is significantly muffled!" ) );
7698 }
7699
7701 "shout", shout );
7702}
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")
void shout(std::string msg="", bool order=false)
Definition: character.cpp:7639
int get_shout_volume() const
Definition: character.cpp:7596
bool move(avatar &you, map &m, const tripoint &d)
void transform(player &p, const tripoint &pos)
Transform the examined object into the object specified by its transforms_into property.
Definition: iexamine.cpp:1556

References _, Creature::add_msg_if_player(), sounds::alert, bp_mouth, encumb(), get_shout_volume(), has_trait(), Creature::is_player(), Creature::is_underwater(), is_wearing(), itype_id, m_warning, mod_stat(), avatar_action::move(), noise, sounds::order, pos(), shout(), sounds::sound(), trait_GILLS, trait_GILLS_CEPH, trait_PROF_FOODP, trait_SHOUT2, trait_SHOUT3, and iexamine::transform().

Referenced by game::chat(), dialogue::dynamic_line(), shout(), suffer_from_schizophrenia(), and suffer_while_awake().

◆ sight_impaired()

◆ sight_range()

int Character::sight_range ( int  light_level) const
overridevirtual

Returns the player's sight range.

Implements Creature.

Definition at line 606 of file character.cpp.

607{
608 if( light_level == 0 ) {
609 return 1;
610 }
611 /* Via Beer-Lambert we have:
612 * light_level * (1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance) ) <= LIGHT_AMBIENT_LOW
613 * Solving for distance:
614 * 1 / exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) <= LIGHT_AMBIENT_LOW / light_level
615 * 1 <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW / light_level
616 * light_level <= exp( LIGHT_TRANSPARENCY_OPEN_AIR * distance ) * LIGHT_AMBIENT_LOW
617 * log(light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance + log(LIGHT_AMBIENT_LOW)
618 * log(light_level) - log(LIGHT_AMBIENT_LOW) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
619 * log(LIGHT_AMBIENT_LOW / light_level) <= LIGHT_TRANSPARENCY_OPEN_AIR * distance
620 * log(LIGHT_AMBIENT_LOW / light_level) * (1 / LIGHT_TRANSPARENCY_OPEN_AIR) <= distance
621 */
622 int range = static_cast<int>( -std::log( get_vision_threshold( static_cast<int>
623 ( get_map().ambient_light_at( pos() ) ) ) / static_cast<float>( light_level ) ) *
624 ( 1.0 / LIGHT_TRANSPARENCY_OPEN_AIR ) );
625
626 // Clamp to [1, sight_max].
627 return clamp( range, 1, sight_max );
628}
float get_vision_threshold(float light_level) const
Returns the apparent light level at which the player can see.
Definition: character.cpp:1736
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36

References clamp(), get_map(), get_vision_threshold(), LIGHT_TRANSPARENCY_OPEN_AIR, pos(), range, and sight_max.

Referenced by game::calc_driving_offset(), overmap_sight_range(), sees_with_infrared(), and editmap::update_view_with_help().

◆ skin_name()

std::string Character::skin_name ( ) const
overridevirtual

Returns the name of the player's outer layer, e.g.

"armor plates"

Implements Creature.

Definition at line 595 of file character.cpp.

596{
597 // TODO: Return actual deflecting layer name
598 return _( "armor" );
599}

References _.

◆ sound_hallu()

void Character::sound_hallu ( )

Creates an auditory hallucination.

Definition at line 1660 of file suffer.cpp.

1661{
1662 // Random 'dangerous' sound from a random direction
1663 // 1/5 chance to be a loud sound
1664 std::vector<std::string> dir{ "north",
1665 "northeast",
1666 "northwest",
1667 "south",
1668 "southeast",
1669 "southwest",
1670 "east",
1671 "west" };
1672
1673 std::vector<std::string> dirz{ "and above you ", "and below you " };
1674
1675 std::vector<std::tuple<std::string, std::string, std::string>> desc{
1676 std::make_tuple( "whump!", "smash_fail", "t_door_c" ),
1677 std::make_tuple( "crash!", "smash_success", "t_door_c" ),
1678 std::make_tuple( "glass breaking!", "smash_success", "t_window_domestic" ) };
1679
1680 std::vector<std::tuple<std::string, std::string, std::string>> desc_big{
1681 std::make_tuple( "huge explosion!", "explosion", "default" ),
1682 std::make_tuple( "bang!", "fire_gun", "glock_19" ),
1683 std::make_tuple( "blam!", "fire_gun", "mossberg_500" ),
1684 std::make_tuple( "crash!", "smash_success", "t_wall" ),
1685 std::make_tuple( "SMASH!", "smash_success", "t_wall" ) };
1686
1687 std::string i_dir = dir[rng( 0, dir.size() - 1 )];
1688
1689 if( one_in( 10 ) ) {
1690 i_dir += " " + dirz[rng( 0, dirz.size() - 1 )];
1691 }
1692
1693 std::string i_desc;
1694 std::pair<std::string, std::string> i_sound;
1695 if( one_in( 5 ) ) {
1696 int r_int = rng( 0, desc_big.size() - 1 );
1697 i_desc = std::get<0>( desc_big[r_int] );
1698 i_sound = std::make_pair( std::get<1>( desc_big[r_int] ), std::get<2>( desc_big[r_int] ) );
1699 } else {
1700 int r_int = rng( 0, desc.size() - 1 );
1701 i_desc = std::get<0>( desc[r_int] );
1702 i_sound = std::make_pair( std::get<1>( desc[r_int] ), std::get<2>( desc[r_int] ) );
1703 }
1704
1705 add_msg( m_warning, _( "From the %1$s you hear %2$s" ), i_dir, i_desc );
1706 sfx::play_variant_sound( i_sound.first, i_sound.second, rng( 20, 80 ) );
1707}
void play_variant_sound(const std::string &id, const std::string &variant, int volume, units::angle angle, double pitch_min=-1.0, double pitch_max=-1.0)
Definition: sounds.cpp:1598

References _, add_msg(), m_warning, one_in(), sfx::play_variant_sound(), and rng().

Referenced by hardcoded_effects(), and suffer_from_schizophrenia().

◆ speed_rating()

float Character::speed_rating ( ) const
overridevirtual

Returns an approximate number of tiles this creature can travel per turn.

Implements Creature.

Reimplemented in npc.

Definition at line 10006 of file character.cpp.

10007{
10008 float ret = get_speed() / 100.0f;
10009 ret *= 100.0f / run_cost( 100, false );
10010 // Adjustment for player being able to run, but not doing so at the moment
10011 if( move_mode != CMM_RUN ) {
10012 ret *= 1.0f + ( static_cast<float>( get_stamina() ) / static_cast<float>( get_stamina_max() ) );
10013 }
10014 return ret;
10015}
int run_cost(int base_cost, bool diag=false) const
Returns the player's modified base movement cost.

References CMM_RUN, get_speed(), get_stamina(), get_stamina_max(), move_mode, cata::hash64_detail::ret, and run_cost().

◆ spores()

void Character::spores ( )

Definition at line 8783 of file character.cpp.

8784{
8785 map &here = get_map();
8786 fungal_effects fe( *g, here );
8787 //~spore-release sound
8788 sounds::sound( pos(), 10, sounds::sound_t::combat, _( "Pouf!" ), false, "misc", "puff" );
8789 for( const tripoint &sporep : here.points_in_radius( pos(), 1 ) ) {
8790 if( sporep == pos() ) {
8791 continue;
8792 }
8793 fe.fungalize( sporep, this, 0.25 );
8794 }
8795}

References _, sounds::combat, fungal_effects::fungalize(), g, get_map(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), pos(), and sounds::sound().

Referenced by activate_mutation(), hardcoded_effects(), and suffer_while_awake().

◆ stability_roll()

float Character::stability_roll ( ) const
overridevirtual

Returns value of player's stable footing.

Strength improves player stability roll Perception slightly improves player stability roll Dexterity slightly improves player stability roll Melee improves player stability roll

Implements Creature.

Definition at line 10649 of file character.cpp.

10650{
10651 /** @EFFECT_STR improves player stability roll */
10652
10653 /** @EFFECT_PER slightly improves player stability roll */
10654
10655 /** @EFFECT_DEX slightly improves player stability roll */
10656
10657 /** @EFFECT_MELEE improves player stability roll */
10658 return get_melee() + get_str() + ( get_per() / 3.0f ) + ( get_dex() / 4.0f );
10659}
float get_melee() const override
Returns melee skill level, to be used to throttle dodge practice.
Definition: melee.cpp:914

References get_dex(), get_melee(), get_per(), and get_str().

Referenced by on_hit().

◆ stamina_move_cost_modifier()

float Character::stamina_move_cost_modifier ( ) const

Definition at line 7158 of file character.cpp.

7159{
7160 // Both walk and run speed drop to half their maximums as stamina approaches 0.
7161 // Convert stamina to a float first to allow for decimal place carrying
7162 float stamina_modifier = ( static_cast<float>( get_stamina() ) / get_stamina_max() + 1 ) / 2;
7163 if( move_mode == CMM_RUN && get_stamina() >= 0 ) {
7164 // Rationale: Average running speed is 2x walking speed. (NOT sprinting)
7165 stamina_modifier *= 2.0;
7166 }
7167 if( move_mode == CMM_CROUCH ) {
7168 stamina_modifier *= 0.5;
7169 }
7170 return stamina_modifier;
7171}

References CMM_CROUCH, CMM_RUN, get_stamina(), get_stamina_max(), and move_mode.

Referenced by burn_move_stamina(), and run_cost().

◆ start_destination_activity()

void Character::start_destination_activity ( )

Definition at line 10528 of file character.cpp.

10529{
10530 if( !has_destination_activity() ) {
10531 debugmsg( "Tried to start invalid destination activity" );
10532 return;
10533 }
10534
10537}
void clear_destination()
bool has_destination_activity() const

References assign_activity(), clear_destination(), debugmsg, get_destination_activity(), and has_destination_activity().

Referenced by game::handle_action(), and npc::move().

◆ start_hauling()

void Character::start_hauling ( )

Definition at line 9173 of file character.cpp.

9174{
9175 add_msg( _( "You start hauling items along the ground." ) );
9176 if( is_armed() ) {
9177 add_msg( m_warning, _( "Your hands are not free, which makes hauling slower." ) );
9178 }
9179 hauling = true;
9180}

References _, add_msg(), hauling, is_armed(), and m_warning.

Referenced by haul().

◆ stop_hauling()

void Character::stop_hauling ( )

Definition at line 9182 of file character.cpp.

9183{
9184 add_msg( _( "You stop hauling items." ) );
9185 hauling = false;
9186 if( has_activity( ACT_MOVE_ITEMS ) ) {
9188 }
9189}

References _, ACT_MOVE_ITEMS, add_msg(), cancel_activity(), has_activity(), and hauling.

Referenced by cancel_activity(), haul(), game::place_player(), avatar::set_movement_mode(), and game::vertical_move().

◆ store()

void Character::store ( JsonOut json) const
protected

Load variables from json into object.

These variables are common to both the avatar and NPCs.

Definition at line 654 of file savegame_json.cpp.

655{
656 Creature::store( json );
657
658 // assumes already in Character object
659 // positional data
660 json.member( "posx", position.x );
661 json.member( "posy", position.y );
662 json.member( "posz", position.z );
663
664 // stat
665 json.member( "str_cur", str_cur );
666 json.member( "str_max", str_max );
667 json.member( "dex_cur", dex_cur );
668 json.member( "dex_max", dex_max );
669 json.member( "int_cur", int_cur );
670 json.member( "int_max", int_max );
671 json.member( "per_cur", per_cur );
672 json.member( "per_max", per_max );
673
674 json.member( "str_bonus", str_bonus );
675 json.member( "dex_bonus", dex_bonus );
676 json.member( "per_bonus", per_bonus );
677 json.member( "int_bonus", int_bonus );
678
679 json.member( "name", name );
680
681 json.member( "base_age", init_age );
682 json.member( "base_height", init_height );
683
684 if( prof.is_valid() ) {
685 json.member( "profession", prof );
686 }
687 json.member( "custom_profession", custom_profession );
688
689 // health
690 json.member( "healthy", healthy );
691 json.member( "healthy_mod", healthy_mod );
692 json.member( "healed_24h", healed_total );
693
694 // status
695 json.member( "temp_cur", temp_cur );
696 json.member( "temp_conv", temp_conv );
697 json.member( "frostbite_timer", frostbite_timer );
698 json.member( "body_wetness", body_wetness );
699
700 // needs
701 json.member( "thirst", thirst );
702 json.member( "fatigue", fatigue );
703 json.member( "sleep_deprivation", sleep_deprivation );
704 json.member( "stored_calories", stored_calories );
705 json.member( "radiation", radiation );
706 json.member( "stamina", stamina );
707 json.member( "vitamin_levels", vitamin_levels );
708 json.member( "pkill", pkill );
709 json.member( "omt_path", omt_path );
710 json.member( "consumption_history", consumption_history );
711
712 // crafting etc
713 json.member( "destination_activity", destination_activity );
714 json.member( "activity", activity );
715 json.member( "stashed_outbounds_activity", stashed_outbounds_activity );
716 json.member( "stashed_outbounds_backlog", stashed_outbounds_backlog );
717 json.member( "backlog", backlog );
718 json.member( "activity_vehicle_part_index", activity_vehicle_part_index ); // NPC activity
719
720 // handling for storing activity requirements
721 if( !backlog.empty() && !backlog.front().str_values.empty() && ( ( activity &&
722 activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) || ( destination_activity &&
723 destination_activity.id() == activity_id( "ACT_FETCH_REQUIRED" ) ) ) ) {
724 requirement_data things_to_fetch = requirement_id( backlog.front().str_values.back() ).obj();
725 json.member( "fetch_data", things_to_fetch );
726 }
727
728 const item &weapon = primary_weapon();
729 if( !weapon.is_null() ) {
730 json.member( "weapon", weapon ); // also saves contents
731 }
732
733 json.member( "stim", stim );
734 json.member( "type_of_scent", type_of_scent );
735
736 // breathing
737 json.member( "oxygen", oxygen );
738
739 // traits: permanent 'mutations' more or less
740 json.member( "traits", my_traits );
741 json.member( "mutations", my_mutations );
742 json.member( "magic", magic );
743 json.member( "martial_arts_data", martial_arts_data );
744 // "Fracking Toasters" - Saul Tigh, toaster
745 json.member( "my_bionics", *my_bionics );
746
747 json.member_as_string( "move_mode", move_mode );
748
749 // storing the mount
750 if( is_mounted() ) {
751 json.member( "mounted_creature", g->critter_tracker->temporary_id( *mounted_creature ) );
752 }
753
754 morale->store( json );
755
756 // skills
757 json.member( "skills" );
758 json.start_object();
759 for( const auto &pair : *_skills ) {
760 json.member( pair.first.str(), pair.second );
761 }
762 json.end_object();
763
764 // npc: unimplemented, potentially useful
765 json.member( "learned_recipes", *learned_recipes );
766 autolearn_skills_stamp->clear(); // Invalidates the cache
767
768 // npc; unimplemented
769 if( power_level < 1_kJ ) {
770 json.member( "power_level", std::to_string( units::to_joule( power_level ) ) + " J" );
771 } else {
772 json.member( "power_level", units::to_kilojoule( power_level ) );
773 }
774 json.member( "max_power_level", units::to_kilojoule( max_power_level ) );
775
776 if( !overmap_time.empty() ) {
777 json.member( "overmap_time" );
778 json.start_array();
779 for( const std::pair<const point_abs_omt, time_duration> &pr : overmap_time ) {
780 json.write( pr.first );
781 json.write( pr.second );
782 }
783 json.end_array();
784 }
785 json.member( "stomach", stomach );
786 json.member( "automoveroute", auto_move_route );
787 json.member( "known_traps" );
788 json.start_array();
789 for( const auto &elem : known_traps ) {
790 json.start_object();
791 json.member( "x", elem.first.x );
792 json.member( "y", elem.first.y );
793 json.member( "z", elem.first.z );
794 json.member( "trap", elem.second );
795 json.end_object();
796 }
797 json.end_array();
798}
void store(JsonOut &jsout) const
These two functions are responsible for storing and loading the members of this class to/from json da...
void member_as_string(const std::string &name, const T &value)
Definition: json.h:746
void end_array()
Definition: json.cpp:2150
void start_array(bool wrap=false)
Definition: json.cpp:2139
void start_object(bool wrap=false)
Definition: json.cpp:2120
void write(T val)
Definition: json.h:615
void end_object()
Definition: json.cpp:2131
void member(const std::string &name)
Definition: json.cpp:2235

References _skills, activity, activity_vehicle_part_index, auto_move_route, autolearn_skills_stamp, backlog, body_wetness, consumption_history, custom_profession, destination_activity, dex_bonus, dex_cur, dex_max, JsonOut::end_array(), JsonOut::end_object(), fatigue, frostbite_timer, g, healed_total, healthy, healthy_mod, player_activity::id(), init_age, init_height, int_bonus, int_cur, int_max, is_mounted(), item::is_null(), string_id< T >::is_valid(), known_traps, learned_recipes, magic, martial_arts_data, max_power_level, JsonOut::member(), JsonOut::member_as_string(), morale, mounted_creature, move_mode, my_bionics, my_mutations, my_traits, name, string_id< T >::obj(), omt_path, overmap_time, oxygen, per_bonus, per_cur, per_max, pkill, position, power_level, primary_weapon(), prof, radiation, sleep_deprivation, stamina, JsonOut::start_array(), JsonOut::start_object(), stashed_outbounds_activity, stashed_outbounds_backlog, stim, stomach, Creature::store(), stored_calories, str_bonus, str_cur, str_max, temp_conv, temp_cur, thirst, units::to_joule(), units::to_kilojoule(), to_string(), type_of_scent, vitamin_levels, JsonOut::write(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by player::store().

◆ suffer()

void Character::suffer ( )

Handles a large number of timers decrementing and other randomized effects.

Definition at line 1522 of file suffer.cpp.

1523{
1524 const int current_stim = get_stim();
1525 // TODO: Remove this section and encapsulate hp_cur
1526 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
1527 if( elem.second.get_hp_cur() <= 0 ) {
1528 add_effect( effect_disabled, 1_turns, elem.first->token );
1529 }
1530 }
1531
1532 for( bionic &bio : *my_bionics ) {
1533 process_bionic( bio );
1534 }
1535
1536 for( std::pair<const trait_id, char_trait_data> &mut : my_mutations ) {
1537 const mutation_branch &mdata = mut.first.obj();
1538 if( calendar::once_every( 1_minutes ) ) {
1539 suffer_water_damage( mdata );
1540 }
1541 char_trait_data &tdata = mut.second;
1542 if( tdata.powered ) {
1543 suffer_mutation_power( mdata, tdata );
1544 }
1545 }
1546
1547 if( is_underwater() ) {
1549 }
1550
1552
1553 if( !in_sleep_state() ) {
1554 suffer_while_awake( current_stim );
1555 } // Done with while-awake-only effects
1556
1557 if( has_trait( trait_ASTHMA ) ) {
1558 suffer_from_asthma( current_stim );
1559 }
1562 }
1563
1569 suffer_from_stimulants( current_stim );
1571 // Stimulants can lessen the PERCEIVED effects of sleep deprivation, but
1572 // they do nothing to cure it. As such, abuse is even more dangerous now.
1573 if( current_stim > 0 ) {
1574 // 100% of blacking out = 20160sd ; Max. stim modifier = 12500sd @ 250stim
1575 // Note: Very high stim already has its own slew of bad effects,
1576 // so the "useful" part of this bonus is actually lower.
1577 sleep_deprivation -= current_stim * 50;
1578 }
1579
1581 //Suffer from enchantments
1582 enchantment_cache->activate_passive( *this );
1583
1584 if( calendar::once_every( 1_hours ) ) {
1586 }
1587}
void suffer_in_sunlight()
Definition: suffer.cpp:797
void suffer_from_artifacts()
Definition: suffer.cpp:1371
void suffer_feral_kill_withdrawl()
Definition: suffer.cpp:717
void suffer_from_addictions()
Definition: suffer.cpp:265
void suffer_from_stimulants(int current_stim)
Definition: suffer.cpp:1393
void suffer_mutation_power(const mutation_branch &mdata, char_trait_data &tdata)
Definition: suffer.cpp:195
void suffer_water_damage(const mutation_branch &mdata)
suffer() subcalls
Definition: suffer.cpp:175
void suffer_while_awake(int current_stim)
Definition: suffer.cpp:292
void process_bionic(bionic &bio)
Handles bionic effects over time of the entered bionic.
Definition: bionics.cpp:1567
void suffer_from_other_mutations()
Definition: suffer.cpp:1024
void suffer_without_sleep(int sleep_deprivation)
Definition: suffer.cpp:1435
void suffer_while_underwater()
Definition: suffer.cpp:242
void suffer_from_bad_bionics()
Definition: suffer.cpp:1277
void suffer_from_radiation()
Definition: suffer.cpp:1133
void suffer_from_asthma(int current_stim)
Definition: suffer.cpp:609
static const trait_id trait_PROF_FERAL("PROF_FERAL")
static const efftype_id effect_accumulated_mutagen("accumulated_mutagen")
static const efftype_id effect_feral_killed_recently("feral_killed_recently")
static const efftype_id effect_disabled("disabled")
static const trait_id trait_ASTHMA("ASTHMA")

References Creature::add_effect(), effect_accumulated_mutagen, effect_disabled, effect_feral_killed_recently, enchantment_cache, Creature::get_body(), get_sleep_deprivation(), get_stim(), Creature::has_effect(), has_trait(), in_sleep_state(), Creature::is_underwater(), my_bionics, my_mutations, num_bp, calendar::once_every(), char_trait_data::powered, process_bionic(), sleep_deprivation, suffer_feral_kill_withdrawl(), suffer_from_addictions(), suffer_from_artifacts(), suffer_from_asthma(), suffer_from_bad_bionics(), suffer_from_other_mutations(), suffer_from_radiation(), suffer_from_stimulants(), suffer_in_sunlight(), suffer_mutation_power(), suffer_water_damage(), suffer_while_awake(), suffer_while_underwater(), suffer_without_sleep(), trait_ASTHMA, and trait_PROF_FERAL.

Referenced by process_turn().

◆ suffer_feral_kill_withdrawl()

void Character::suffer_feral_kill_withdrawl ( )
private

Definition at line 717 of file suffer.cpp.

718{
719 // If we somehow triggered this while content with our bloodshed, cancel.
721 return;
722 }
723 // Once every 4 hours
724 if( calendar::once_every( 4_hours ) ) {
725 // Select a random side effect:
726 switch( dice( 1, 4 ) ) {
727 default:
728 case 1:
729 // Feel ill, overcome with nausea if awake. Additional chance of unexplained bleeding.
730 mod_healthy_mod( -50, -500 );
731 if( !in_sleep_state() ) {
732 add_msg_if_player( m_bad, _( "You feel as if your insides are rotting away." ) );
733 vomit();
734 if( one_in( 3 ) ) {
735 add_msg_if_player( m_bad, _( "Blood starts leaking from your eyes and nose." ) );
736 add_effect( effect_bleed, 10_minutes, bp_head );
737 add_effect( effect_blind, rng( 1_seconds, 30_seconds ) );
738 }
739 } else {
740 add_msg_if_player( m_bad, _( "You feel a bit queasy in your sleep." ) );
741 if( one_in( 3 ) ) {
742 add_msg_if_player( m_bad, _( "You wake up bloody for some reason." ) );
743 wake_up();
744 add_effect( effect_bleed, 10_minutes, bp_head );
745 add_effect( effect_blind, rng( 1_seconds, 30_seconds ) );
746 }
747 }
748 break;
749 case 2:
750 // Empty stamina and inflict fatigue, pain if awake.
751 mod_fatigue( rng( 5, 10 ) );
752 set_stamina( get_stamina() * 1 / ( rng( 3, 8 ) ) );
753 if( !in_sleep_state() ) {
754 add_msg_if_player( m_bad, _( "Your head aches as a wave of exhaustion passes through you." ) );
755 mod_pain( rng( 10, 25 ) );
756 } else {
757 add_msg_if_player( m_bad, _( "You stir restlessly in your sleep." ) );
758 }
759 break;
760 case 3:
761 // Adrenaline rush plus side effects from panic. Chance it will wake you up anyway.
762 if( !in_sleep_state() ) {
763 add_msg_if_player( m_bad, _( "A pang of terror stirs your fight-or-flight response!" ) );
764 add_effect( effect_adrenaline, rng( 3_minutes, 5_minutes ) );
765 mod_stim( rng( 5, 10 ) );
766 add_morale( MORALE_FEELING_BAD, -5, -25, 10_minutes, 3_minutes, true );
767 } else {
768 if( !one_in( 4 ) ) {
769 add_msg_if_player( m_bad, _( "You jolt awake in a panic attack!" ) );
770 wake_up();
771 add_effect( effect_adrenaline, rng( 3_minutes, 5_minutes ) );
772 mod_stim( rng( 5, 10 ) );
773 add_morale( MORALE_FEELING_BAD, -5, -25, 10_minutes, 3_minutes, true );
774 } else {
775 add_msg_if_player( m_bad, _( "You have a vivid nightmare that almost wakes you up." ) );
776 }
777 }
778 break;
779 case 4:
780 // The others are displeased with your lack of bloodshed, can sleep through the mental contact itself.
781 add_effect( effect_attention, rng( 3_hours, 6_hours ), num_bp, rng( 1, 4 ), false, true );
782 if( !in_sleep_state() ) {
784 _( "You feel like something is judging you from afar, leaving your head spinning." ) );
785 add_effect( effect_shakes, 5_minutes );
786 add_effect( effect_stunned, rng( 1_turns, 10_turns ) );
787 } else {
789 _( "You have a vivid nightmare about being deemed unworthy by a higher power." ) );
790 }
791 break;
792 }
793 }
794
795}
static const efftype_id effect_blind("blind")
static const efftype_id effect_bleed("bleed")
static const efftype_id effect_adrenaline("adrenaline")
static const efftype_id effect_attention("attention")
static const efftype_id effect_shakes("shakes")
static const efftype_id effect_stunned("stunned")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_if_player(), bp_head, dice(), effect_adrenaline, effect_attention, effect_bleed, effect_blind, effect_feral_killed_recently, effect_shakes, effect_stunned, get_stamina(), Creature::has_effect(), in_sleep_state(), m_bad, mod_fatigue(), mod_healthy_mod(), mod_pain(), mod_stim(), MORALE_FEELING_BAD, num_bp, calendar::once_every(), one_in(), rng(), set_stamina(), vomit(), and wake_up().

Referenced by suffer().

◆ suffer_from_addictions()

void Character::suffer_from_addictions ( )
private

Definition at line 265 of file suffer.cpp.

266{
267 time_duration timer = -6_hours;
268 if( has_trait( trait_ADDICTIVE ) ) {
269 timer = -10_hours;
270 } else if( has_trait( trait_NONADDICTIVE ) ) {
271 timer = -3_hours;
272 }
273 for( addiction &cur_addiction : addictions ) {
274 if( cur_addiction.sated <= 0_turns &&
275 cur_addiction.intensity >= MIN_ADDICTION_LEVEL ) {
276 addict_effect( *this, cur_addiction );
277 }
278 cur_addiction.sated -= 1_turns;
279 // Higher intensity addictions heal faster
280 if( cur_addiction.sated - 10_minutes * cur_addiction.intensity < timer ) {
281 if( cur_addiction.intensity <= 2 ) {
282 rem_addiction( cur_addiction.type );
283 break;
284 } else {
285 cur_addiction.intensity--;
286 cur_addiction.sated = 0_turns;
287 }
288 }
289 }
290}
void addict_effect(Character &u, addiction &add)
Definition: addiction.cpp:57
constexpr int MIN_ADDICTION_LEVEL
Definition: addiction.h:13
void rem_addiction(add_type type)
Removes an addition from the player.
Definition: suffer.cpp:1900

References addict_effect(), addictions, has_trait(), MIN_ADDICTION_LEVEL, rem_addiction(), trait_ADDICTIVE, and trait_NONADDICTIVE.

Referenced by suffer().

◆ suffer_from_artifacts()

void Character::suffer_from_artifacts ( )
private

Definition at line 1371 of file suffer.cpp.

1372{
1373 // Artifact effects
1375 add_effect( effect_attention, 3_turns );
1376 }
1377
1379 get_weather().weather_id->precip < precip_class::heavy ) {
1383 }
1384
1385 if( has_artifact_with( AEP_MUTAGENIC ) && one_turn_in( 48_hours ) ) {
1386 mutate();
1387 }
1388 if( has_artifact_with( AEP_FORCE_TELEPORT ) && one_turn_in( 1_hours ) ) {
1389 teleport::teleport( *this );
1390 }
1391}
const weather_type_id & get_bad_weather() const
weather_type_id weather_override
Definition: weather.h:199
@ AEP_MUTAGENIC
Definition: enums.h:130
@ AEP_FORCE_TELEPORT
Definition: enums.h:138
@ AEP_ATTENTION
Definition: enums.h:131
@ AEP_BAD_WEATHER
Definition: enums.h:140
const weather_generator & get_cur_weather_gen() const
Definition: weather.cpp:1052
void set_nextweather(time_point t)
Definition: weather.cpp:1107

References Creature::add_effect(), AEP_ATTENTION, AEP_BAD_WEATHER, AEP_FORCE_TELEPORT, AEP_MUTAGENIC, effect_attention, weather_generator::get_bad_weather(), weather_manager::get_cur_weather_gen(), get_weather(), has_artifact_with(), heavy, mutate(), calendar::once_every(), one_turn_in(), weather_manager::set_nextweather(), teleport::teleport(), calendar::turn, and weather_manager::weather_override.

Referenced by suffer().

◆ suffer_from_asthma()

void Character::suffer_from_asthma ( int  current_stim)
private

Definition at line 609 of file suffer.cpp.

610{
614 return;
615 }
616 // Cap effect of stimulants on asthma attacks to 1 per minute (or risk instantly killing players that rely on oxygen tanks)
617 if( !one_in( std::max( to_turns<int>( 1_minutes ),
618 ( to_turns<int>( 6_hours ) - current_stim * 180 ) ) *
620 1 ) ) ) {
621 return;
622 }
623 bool auto_use = has_charges( itype_inhaler, 1 ) || has_charges( itype_oxygen_tank, 1 ) ||
625 bool oxygenator = has_bionic( bio_gills ) && get_power_level() >= ( bio_gills->power_trigger / 8 );
626 if( is_underwater() ) {
627 oxygen = oxygen / 2;
628 auto_use = false;
629 }
630
631 add_msg_player_or_npc( m_bad, _( "You have an asthma attack!" ),
632 "<npcname> starts wheezing and coughing." );
633
635 inventory map_inv;
636 map_inv.form_from_map( g->u.pos(), 2, &g->u );
637 // check if an inhaler is somewhere near
638 bool nearby_use = auto_use || oxygenator || map_inv.has_charges( itype_inhaler, 1 ) ||
639 map_inv.has_charges( itype_oxygen_tank, 1 ) ||
640 map_inv.has_charges( itype_smoxygen_tank, 1 );
641 // check if character has an oxygenator first
642 if( oxygenator ) {
644 add_msg_if_player( m_info, _( "You use your Oxygenator to clear it up, "
645 "then go back to sleep." ) );
646 } else if( auto_use ) {
648 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
649 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
650 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
652 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
653 "and go back to sleep." ) );
654 }
655 } else if( nearby_use ) {
656 // create new variable to resolve a reference issue
657 int amount = 1;
658 map &here = get_map();
659 if( !here.use_charges( g->u.pos(), 2, itype_inhaler, amount ).empty() ) {
660 add_msg_if_player( m_info, _( "You use your inhaler and go back to sleep." ) );
661 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
662 } else if( !here.use_charges( g->u.pos(), 2, itype_oxygen_tank, amount ).empty() ||
663 !here.use_charges( g->u.pos(), 2, itype_smoxygen_tank, amount ).empty() ) {
664 add_msg_if_player( m_info, _( "You take a deep breath from your oxygen tank "
665 "and go back to sleep." ) );
666 }
667 } else {
668 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
669 if( has_effect( effect_sleep ) ) {
670 wake_up();
671 } else {
672 if( !is_npc() ) {
673 g->cancel_activity_or_ignore_query( distraction_type::asthma,
674 _( "You can't focus while choking!" ) );
675 }
676 }
677 }
678 } else if( auto_use ) {
679 int charges = 0;
681 moves -= 40;
682 charges = charges_of( itype_inhaler );
683 if( charges == 0 ) {
684 add_msg_if_player( m_bad, _( "You use your last inhaler charge." ) );
685 } else {
686 add_msg_if_player( m_info, vgettext( "You use your inhaler, "
687 "only %d charge left.",
688 "You use your inhaler, "
689 "only %d charges left.", charges ),
690 charges );
691 }
692 add_effect( effect_took_antiasthmatic, rng( 1_hours, 2_hours ) );
693 } else if( use_charges_if_avail( itype_oxygen_tank, 1 ) ||
695 moves -= 500; // synched with use action
697 if( charges == 0 ) {
698 add_msg_if_player( m_bad, _( "You breathe in last bit of oxygen "
699 "from the tank." ) );
700 } else {
701 add_msg_if_player( m_info, vgettext( "You take a deep breath from your oxygen "
702 "tank, only %d charge left.",
703 "You take a deep breath from your oxygen "
704 "tank, only %d charges left.", charges ),
705 charges );
706 }
707 }
708 } else {
709 add_effect( effect_asthma, rng( 5_minutes, 20_minutes ) );
710 if( !is_npc() ) {
711 g->cancel_activity_or_ignore_query( distraction_type::asthma,
712 _( "You can't focus while choking!" ) );
713 }
714 }
715}
bool use_charges_if_avail(const itype_id &it, int quantity)
Definition: character.cpp:9659
bool has_charges(const itype_id &it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >) const
Definition: inventory.cpp:894
static const efftype_id effect_datura("datura")
static const efftype_id effect_narcosis("narcosis")
static const efftype_id effect_asthma("asthma")
static const itype_id itype_oxygen_tank("oxygen_tank")
static const itype_id itype_inhaler("inhaler")
static const itype_id itype_smoxygen_tank("smoxygen_tank")
static const efftype_id effect_cough_aggravated_asthma("cough_aggravated_asthma")
static const efftype_id effect_sleep("sleep")
static const bionic_id bio_gills("bio_gills")
static const efftype_id effect_took_antiasthmatic("took_antiasthmatic")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), asthma, bio_gills, visitable< Character >::charges_of(), effect_adrenaline, effect_asthma, effect_cough_aggravated_asthma, effect_datura, effect_narcosis, effect_sleep, effect_took_antiasthmatic, inventory::form_from_map(), g, get_map(), get_power_level(), has_bionic(), has_charges(), inventory::has_charges(), Creature::has_effect(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), in_sleep_state(), Creature::is_npc(), Creature::is_underwater(), itype_inhaler, itype_oxygen_tank, itype_smoxygen_tank, m_bad, m_info, mod_power_level(), Creature::moves, one_in(), oxygen, bionic_data::power_trigger, rng(), use_charges_if_avail(), vgettext(), and wake_up().

Referenced by suffer().

◆ suffer_from_bad_bionics()

void Character::suffer_from_bad_bionics ( )
private

Definition at line 1277 of file suffer.cpp.

1278{
1279 // Negative bionics effects
1281 one_turn_in( 2_hours ) &&
1283 add_msg_if_player( m_bad, _( "You suffer a painful electrical discharge!" ) );
1284 mod_pain( 1 );
1285 moves -= 150;
1287
1288 item &weapon = primary_weapon();
1289 if( weapon.typeId() == itype_e_handcuffs && weapon.charges > 0 ) {
1290 weapon.charges -= rng( 1, 3 ) * 50;
1291 if( weapon.charges < 1 ) {
1292 weapon.charges = 1;
1293 }
1294
1295 add_msg_if_player( m_good, _( "The %s seems to be affected by the discharge." ),
1296 weapon.tname() );
1297 }
1298 sfx::play_variant_sound( "bionics", "elec_discharge", 100 );
1299 }
1300 if( has_bionic( bio_dis_acid ) && one_turn_in( 150_minutes ) ) {
1301 add_msg_if_player( m_bad, _( "You suffer a burning acidic discharge!" ) );
1302 hurtall( 1, nullptr );
1303 sfx::play_variant_sound( "bionics", "acid_discharge", 100 );
1304 sfx::do_player_death_hurt( g->u, false );
1305 }
1306 if( has_bionic( bio_drain ) && get_power_level() > 24_kJ && one_turn_in( 1_hours ) ) {
1307 add_msg_if_player( m_bad, _( "Your batteries discharge slightly." ) );
1308 mod_power_level( -25_kJ );
1309 sfx::play_variant_sound( "bionics", "elec_crackle_low", 100 );
1310 }
1311 if( has_bionic( bio_noise ) && one_turn_in( 50_minutes ) &&
1313 // TODO: NPCs with said bionic
1314 if( !is_deaf() ) {
1315 add_msg( m_bad, _( "A bionic emits a crackle of noise!" ) );
1316 sfx::play_variant_sound( "bionics", "elec_blast", 100 );
1317 } else {
1318 add_msg_if_player( m_bad, _( "You feel your faulty bionic shuddering." ) );
1319 sfx::play_variant_sound( "bionics", "elec_blast_muffled", 100 );
1320 }
1321 sounds::sound( pos(), 60, sounds::sound_t::movement, _( "Crackle!" ) ); //sfx above
1322 }
1324 get_power_level() >= get_max_power_level() * .75 ) {
1325 mod_str_bonus( -3 );
1326 }
1327 if( has_bionic( bio_trip ) && one_turn_in( 50_minutes ) &&
1330 add_msg_if_player( m_bad, _( "Your vision pixelates!" ) );
1331 add_effect( effect_visuals, 10_minutes );
1332 sfx::play_variant_sound( "bionics", "pixelated", 100 );
1333 }
1334 if( has_bionic( bio_spasm ) && one_turn_in( 5_hours ) && !has_effect( effect_downed ) &&
1337 _( "Your malfunctioning bionic causes you to spasm and fall to the floor!" ),
1338 _( "<npcname> spasms and falls to the floor!" ) );
1339 mod_pain( 1 );
1340 add_effect( effect_stunned, 1_turns );
1341 add_effect( effect_downed, 10_turns, num_bp, 0 );
1342 sfx::play_variant_sound( "bionics", "elec_crackle_high", 100 );
1343 }
1345 one_turn_in( 2_hours ) ) {
1346 add_msg_if_player( m_bad, _( "Your bionics short-circuit, causing you to tremble and shiver." ) );
1348 add_effect( effect_shakes, 5_minutes );
1349 sfx::play_variant_sound( "bionics", "elec_crackle_med", 100 );
1350 }
1351 if( has_bionic( bio_leaky ) && one_turn_in( 6_minutes ) ) {
1352 mod_healthy_mod( -1, -200 );
1353 }
1354 if( has_bionic( bio_sleepy ) && one_turn_in( 50_minutes ) && !in_sleep_state() ) {
1355 mod_fatigue( 1 );
1356 }
1357 if( has_bionic( bio_itchy ) && one_turn_in( 50_minutes ) && !has_effect( effect_formication ) &&
1359 add_msg_if_player( m_bad, _( "Your malfunctioning bionic itches!" ) );
1360 body_part bp = random_body_part( true );
1361 add_effect( effect_formication, 10_minutes, bp );
1362 }
1363 if( has_bionic( bio_glowy ) && !has_effect( effect_glowy_led ) && one_turn_in( 50_minutes ) &&
1365 add_msg_if_player( m_bad, _( "Your malfunctioning bionic starts to glow!" ) );
1366 add_effect( effect_glowy_led, 5_minutes );
1368 }
1369}
body_part random_body_part(bool main_parts_only)
Returns a random body_part token.
Definition: bodypart.cpp:366
void do_player_death_hurt(const player &target, bool death)
Definition: sounds.cpp:1632
static const bionic_id bio_shakes("bio_shakes")
static const efftype_id effect_glowy_led("glowy_led")
static const efftype_id effect_downed("downed")
static const bionic_id bio_power_weakness("bio_power_weakness")
static const bionic_id bio_dis_shock("bio_dis_shock")
static const bionic_id bio_glowy("bio_glowy")
static const efftype_id effect_visuals("visuals")
static const bionic_id bio_trip("bio_trip")
static const bionic_id bio_dis_acid("bio_dis_acid")
static const itype_id itype_e_handcuffs("e_handcuffs")
static const bionic_id bio_spasm("bio_spasm")
static const bionic_id bio_sleepy("bio_sleepy")
static const bionic_id bio_noise("bio_noise")
static const efftype_id effect_formication("formication")
static const bionic_id bio_drain("bio_drain")
static const bionic_id bio_itchy("bio_itchy")
static const bionic_id bio_leaky("bio_leaky")

References _, Creature::add_effect(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), bio_dis_acid, bio_dis_shock, bio_drain, bio_glowy, bio_itchy, bio_leaky, bio_noise, bio_power_weakness, bio_shakes, bio_sleepy, bio_spasm, bio_trip, item::charges, sfx::do_player_death_hurt(), effect_downed, effect_formication, effect_glowy_led, effect_narcosis, effect_shakes, effect_stunned, effect_visuals, g, get_max_power_level(), get_power_level(), has_bionic(), Creature::has_effect(), has_max_power(), hurtall(), in_sleep_state(), is_deaf(), itype_e_handcuffs, m_bad, m_good, m_warning, mod_fatigue(), mod_healthy_mod(), mod_pain(), mod_power_level(), mod_str_bonus(), sounds::movement, Creature::moves, num_bp, one_turn_in(), sfx::play_variant_sound(), pos(), bionic_data::power_trigger, primary_weapon(), random_body_part(), rng(), sounds::sound(), item::tname(), and item::typeId().

Referenced by suffer().

◆ suffer_from_chemimbalance()

void Character::suffer_from_chemimbalance ( )
private

Definition at line 359 of file suffer.cpp.

360{
361 if( one_turn_in( 6_hours ) && !has_trait( trait_NOPAIN ) ) {
362 add_msg_if_player( m_bad, _( "You suddenly feel sharp pain for no reason." ) );
363 mod_pain( 3 * rng( 1, 3 ) );
364 }
365 if( one_turn_in( 6_hours ) ) {
366 int pkilladd = 5 * rng( -1, 2 );
367 if( pkilladd > 0 ) {
368 add_msg_if_player( m_bad, _( "You suddenly feel numb." ) );
369 } else if( ( pkilladd < 0 ) && ( !( has_trait( trait_NOPAIN ) ) ) ) {
370 add_msg_if_player( m_bad, _( "You suddenly ache." ) );
371 }
372 mod_painkiller( pkilladd );
373 }
374 if( one_turn_in( 6_hours ) && !has_effect( effect_sleep ) ) {
375 add_msg_if_player( m_bad, _( "You feel dizzy for a moment." ) );
376 moves -= rng( 10, 30 );
377 }
378 if( one_turn_in( 6_hours ) ) {
379 int hungadd = 5 * rng( -1, 3 );
380 if( hungadd > 0 ) {
381 add_msg_if_player( m_bad, _( "You suddenly feel hungry." ) );
382 } else {
383 add_msg_if_player( m_good, _( "You suddenly feel a little full." ) );
384 }
385 mod_stored_kcal( -10 * hungadd );
386 }
387 if( one_turn_in( 6_hours ) ) {
388 add_msg_if_player( m_bad, _( "You suddenly feel thirsty." ) );
389 mod_thirst( 5 * rng( 1, 3 ) );
390 }
391 if( one_turn_in( 6_hours ) ) {
392 add_msg_if_player( m_good, _( "You feel fatigued all of a sudden." ) );
393 mod_fatigue( 10 * rng( 2, 4 ) );
394 }
395 if( one_turn_in( 8_hours ) ) {
396 if( one_in( 3 ) ) {
398 } else {
399 add_morale( MORALE_FEELING_BAD, -20, -100 );
400 }
401 }
402 if( one_turn_in( 6_hours ) ) {
403 if( one_in( 3 ) ) {
404 add_msg_if_player( m_bad, _( "You suddenly feel very cold." ) );
406 } else {
407 add_msg_if_player( m_bad, _( "You suddenly feel cold." ) );
408 temp_cur.fill( BODYTEMP_COLD );
409 }
411 }
412 if( one_turn_in( 6_hours ) ) {
413 if( one_in( 3 ) ) {
414 add_msg_if_player( m_bad, _( "You suddenly feel very hot." ) );
416 } else {
417 add_msg_if_player( m_bad, _( "You suddenly feel hot." ) );
418 temp_cur.fill( BODYTEMP_HOT );
419 }
421 }
422}
static const trait_id trait_NOPAIN("NOPAIN")

References _, add_morale(), Creature::add_msg_if_player(), BODYTEMP_COLD, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, bp_eyes, effect_sleep, Creature::has_effect(), has_trait(), m_bad, m_good, mod_fatigue(), mod_pain(), mod_painkiller(), mod_stored_kcal(), mod_thirst(), MORALE_FEELING_BAD, MORALE_FEELING_GOOD, Creature::moves, one_in(), one_turn_in(), rng(), temp_cur, and trait_NOPAIN.

Referenced by suffer_while_awake().

◆ suffer_from_other_mutations()

void Character::suffer_from_other_mutations ( )
private

Definition at line 1024 of file suffer.cpp.

1025{
1026 map &here = get_map();
1027 if( has_trait( trait_SHARKTEETH ) && one_turn_in( 24_hours ) ) {
1028 add_msg_if_player( m_neutral, _( "You shed a tooth!" ) );
1029 here.spawn_item( pos(), "bone", 1 );
1030 }
1031
1033 //~Sound of buzzing Insect Wings
1034 sounds::sound( pos(), 10, sounds::sound_t::movement, _( "BZZZZZ" ), false, "misc",
1035 "insect_wings" );
1036 }
1037
1038 bool wearing_shoes = is_wearing_shoes( side::LEFT ) || is_wearing_shoes( side::RIGHT );
1039 int root_vitamins = 0;
1040 int root_water = 0;
1041 if( has_trait( trait_ROOTS3 ) && here.has_flag( flag_PLOWABLE, pos() ) && !wearing_shoes ) {
1042 root_vitamins += 1;
1044 root_water += 51;
1045 }
1046 }
1047
1048 if( x_in_y( root_vitamins, 576 ) ) {
1049 vitamin_mod( vitamin_id( "iron" ), 1, true );
1050 vitamin_mod( vitamin_id( "calcium" ), 1, true );
1051 mod_healthy_mod( 5, 50 );
1052 }
1053
1054 if( x_in_y( root_water, 2550 ) ) {
1055 // Plants draw some crazy amounts of water from the ground in real life,
1056 // so these numbers try to reflect that uncertain but large amount
1057 // this should take 12 hours to meet your daily needs with ROOTS2, and 8 with ROOTS3
1058 mod_thirst( -1 );
1059 }
1060
1061 if( has_trait( trait_SORES ) ) {
1062 for( const body_part bp : all_body_parts ) {
1063 if( bp == bp_head ) {
1064 continue;
1065 }
1066 int sores_pain = 5 + 0.4 * std::abs( encumb( bp ) );
1067 if( get_pain() < sores_pain ) {
1068 set_pain( sores_pain );
1069 }
1070 }
1071 }
1072 //Web Weavers...weave web
1074 // this adds intensity to if its not already there.
1075 here.add_field( pos(), fd_web, 1 );
1076
1077 }
1078
1079 // Blind/Deaf for brief periods about once an hour,
1080 // and visuals about once every 30 min.
1081 if( has_trait( trait_PER_SLIME ) ) {
1082 if( one_turn_in( 1_hours ) && !has_effect( effect_deaf ) ) {
1083 add_msg_if_player( m_bad, _( "Suddenly, you can't hear anything!" ) );
1084 add_effect( effect_deaf, rng( 20_minutes, 60_minutes ) );
1085 }
1086 if( one_turn_in( 1_hours ) && !( has_effect( effect_blind ) ) ) {
1087 add_msg_if_player( m_bad, _( "Suddenly, your eyes stop working!" ) );
1088 add_effect( effect_blind, rng( 2_minutes, 6_minutes ) );
1089 }
1090 // Yes, you can be blind and hallucinate at the same time.
1091 // Your post-human biology is truly remarkable.
1092 if( one_turn_in( 30_minutes ) && !( has_effect( effect_visuals ) ) ) {
1093 add_msg_if_player( m_bad, _( "Your visual centers must be acting up…" ) );
1094 add_effect( effect_visuals, rng( 36_minutes, 72_minutes ) );
1095 }
1096 }
1097
1098 if( has_trait( trait_WEB_SPINNER ) && !in_vehicle && one_in( 3 ) ) {
1099 // this adds intensity to if its not already there.
1100 here.add_field( pos(), fd_web, 1 );
1101 }
1102
1103 bool should_mutate = has_trait( trait_UNSTABLE ) && !has_trait( trait_CHAOTIC_BAD ) &&
1104 one_turn_in( 48_hours );
1105 should_mutate |= ( has_trait( trait_CHAOTIC ) || has_trait( trait_CHAOTIC_BAD ) ) &&
1106 one_turn_in( 12_hours );
1107 if( should_mutate ) {
1108 mutate();
1109 }
1110
1111 const bool needs_fire = !has_morale( MORALE_PYROMANIA_NEARFIRE ) &&
1113 if( has_trait( trait_PYROMANIA ) && needs_fire && !in_sleep_state() &&
1114 calendar::once_every( 2_hours ) ) {
1115 add_morale( MORALE_PYROMANIA_NOFIRE, -1, -30, 24_hours, 24_hours, true );
1116 if( calendar::once_every( 4_hours ) ) {
1117 const translation smokin_hot_fiyah =
1118 SNIPPET.random_from_category( "pyromania_withdrawal" ).value_or( translation() );
1119 add_msg_if_player( m_bad, "%s", smokin_hot_fiyah );
1120 }
1121 }
1123 calendar::once_every( 2_hours ) ) {
1125 const translation snip = SNIPPET.random_from_category( "killer_withdrawal" ).value_or(
1126 translation() );
1127 add_msg_if_player( m_bad, "%s", snip );
1128 }
1129 add_morale( MORALE_KILLER_NEED_TO_KILL, -1, -30, 24_hours, 24_hours );
1130 }
1131}
bool has_morale(const morale_type &type) const
Definition: character.cpp:9109
const morale_type MORALE_KILLER_HAS_KILLED("morale_killer_has_killed")
const morale_type MORALE_PYROMANIA_STARTFIRE("morale_pyromania_startfire")
const morale_type MORALE_KILLER_NEED_TO_KILL("morale_killer_need_to_kill")
const morale_type MORALE_PYROMANIA_NEARFIRE("morale_pyromania_nearfire")
const morale_type MORALE_PYROMANIA_NOFIRE("morale_pyromania_nofire")
static const trait_id trait_PER_SLIME("PER_SLIME")
static const trait_id trait_SHARKTEETH("SHARKTEETH")
static const trait_id trait_CHAOTIC("CHAOTIC")
static const trait_id trait_UNSTABLE("UNSTABLE")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_deaf("deaf")
static const trait_id trait_WEB_WEAVER("WEB_WEAVER")
static const trait_id trait_CHAOTIC_BAD("CHAOTIC_BAD")
static const trait_id trait_WINGS_INSECT("WINGS_INSECT")
static const trait_id trait_SORES("SORES")
static const trait_id trait_KILLER("KILLER")
static const trait_id trait_WEB_SPINNER("WEB_SPINNER")
static const std::string flag_PLOWABLE("PLOWABLE")
static const trait_id trait_ROOTS3("ROOTS3")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_if_player(), all_body_parts, bp_head, effect_blind, effect_deaf, effect_visuals, encumb(), fd_web, flag_PLOWABLE(), get_map(), Creature::get_pain(), get_thirst(), has_active_mutation(), Creature::has_effect(), has_morale(), has_trait(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), in_sleep_state(), in_vehicle, is_wearing_shoes(), LEFT, m_bad, m_neutral, mod_healthy_mod(), mod_thirst(), MORALE_KILLER_HAS_KILLED, MORALE_KILLER_NEED_TO_KILL, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, MORALE_PYROMANIA_STARTFIRE, sounds::movement, mutate(), calendar::once_every(), one_in(), one_turn_in(), pos(), snippet_library::random_from_category(), RIGHT, rng(), set_pain(), SNIPPET, sounds::sound(), trait_CHAOTIC, trait_CHAOTIC_BAD, trait_KILLER, trait_PER_SLIME, trait_PYROMANIA, trait_ROOTS3, trait_SHARKTEETH, trait_SORES, trait_UNSTABLE, trait_WEB_SPINNER, trait_WEB_WEAVER, trait_WINGS_INSECT, turgid, vitamin_mod(), and x_in_y().

Referenced by suffer().

◆ suffer_from_radiation()

void Character::suffer_from_radiation ( )
private

Definition at line 1133 of file suffer.cpp.

1134{
1135 map &here = get_map();
1136 // checking for radioactive items in inventory
1137 const int item_radiation = leak_level( "RADIOACTIVE" );
1138 const int map_radiation = here.get_radiation( pos() );
1139 float rads = map_radiation / 100.0f + item_radiation / 10.0f;
1140
1141 int rad_mut = 0;
1142 if( has_trait( trait_RADIOACTIVE3 ) ) {
1143 rad_mut = 3;
1144 } else if( has_trait( trait_RADIOACTIVE2 ) ) {
1145 rad_mut = 2;
1146 } else if( has_trait( trait_RADIOACTIVE1 ) ) {
1147 rad_mut = 1;
1148 }
1149
1150 // Spread less radiation when sleeping (slower metabolism etc.)
1151 // Otherwise it can quickly get to the point where you simply can't sleep at all
1152 const bool rad_mut_proc = rad_mut > 0 && x_in_y( rad_mut, to_turns<int>( in_sleep_state() ?
1153 3_hours : 30_minutes ) );
1154
1155 bool has_helmet = false;
1156 const bool power_armored = is_wearing_power_armor( &has_helmet );
1157 const bool rad_resist = power_armored || worn_with_flag( flag_RAD_RESIST );
1158
1159 if( rad_mut > 0 ) {
1160 const bool kept_in = is_rad_immune() || ( rad_resist && !one_in( 4 ) );
1161 if( kept_in ) {
1162 // As if standing on a map tile with radiation level equal to rad_mut
1163 rads += rad_mut / 100.0f;
1164 }
1165
1166 if( rad_mut_proc && !kept_in ) {
1167 // Irradiate a random nearby point
1168 // If you can't, irradiate the player instead
1169 tripoint rad_point = pos() + point( rng( -3, 3 ), rng( -3, 3 ) );
1170 // TODO: Radioactive vehicles?
1171 if( here.get_radiation( rad_point ) < rad_mut ) {
1172 here.adjust_radiation( rad_point, 1 );
1173 } else {
1174 rads += rad_mut;
1175 }
1176 }
1177 }
1178
1179 // Used to control vomiting from radiation to make it not-annoying
1180 bool radiation_increasing = irradiate( rads );
1181
1182 if( radiation_increasing && calendar::once_every( 3_minutes ) && has_bionic( bio_geiger ) ) {
1184 _( "You feel an anomalous sensation coming from "
1185 "your radiation sensors." ) );
1186 }
1187
1188 if( calendar::once_every( 15_minutes ) ) {
1189 if( get_rad() < 0 ) {
1190 set_rad( 0 );
1191 } else if( get_rad() > 2000 ) {
1192 set_rad( 2000 );
1193 }
1194 if( get_option<bool>( "RAD_MUTATION" ) && rng( 100, 10000 ) < get_rad() ) {
1195 mutate();
1196 mod_rad( -50 );
1197 } else if( get_rad() > 50 && rng( 1, 3000 ) < get_rad() && ( stomach.get_calories() > 0 ||
1198 radiation_increasing || !in_sleep_state() ) ) {
1199 vomit();
1200 mod_rad( -1 );
1201 }
1202 }
1203
1204 const bool radiogenic = has_trait( trait_RADIOGENIC );
1205 if( radiogenic && calendar::once_every( 30_minutes ) && get_rad() > 0 ) {
1206 // At 200 irradiation, twice as fast as REGEN
1207 if( x_in_y( get_rad(), 200 ) ) {
1208 healall( 1 );
1209 if( rad_mut == 0 ) {
1210 // Don't heal radiation if we're generating it naturally
1211 // That would counter the main downside of radioactivity
1212 mod_rad( -5 );
1213 }
1214 }
1215 }
1216
1217 if( !radiogenic && get_rad() > 0 ) {
1218 // Even if you heal the radiation itself, the damage is done.
1219 const int hmod = get_healthy_mod();
1220 if( hmod > 200 - get_rad() ) {
1221 set_healthy_mod( std::max( -200, 200 - get_rad() ) );
1222 }
1223 }
1224
1225 if( get_rad() > 200 && calendar::once_every( 10_minutes ) && x_in_y( get_rad(), 1000 ) ) {
1226 hurtall( 1, nullptr );
1227 mod_rad( -5 );
1228 }
1229
1230 // Microreactor CBM
1231 const itype_id &plut_cell = item( "plut_cell" ).typeId();
1232 if( get_fuel_type_available( plut_cell ) > 0 ) {
1233 if( calendar::once_every( 60_minutes ) ) {
1234 int rad_mod = 0;
1235 rad_mod += has_bionic( bio_reactor ) ? 3 : 0;
1236 rad_mod += has_bionic( bio_advreactor ) ? 2 : 0;
1237
1238 if( rad_mod > 1 ) {
1239 mod_rad( rad_mod );
1240 }
1241 }
1242
1243 bool powered_reactor = false;
1244
1245 if( has_bionic( bio_reactor ) ) {
1246 if( get_bionic_state( bio_reactor ).powered ) {
1247 powered_reactor = true;
1248 } else {
1249 mod_power_level( 50_J );
1250 }
1251 }
1252
1253 if( has_bionic( bio_advreactor ) ) {
1254 if( get_bionic_state( bio_advreactor ).powered ) {
1255 powered_reactor = true;
1256 } else {
1257 mod_power_level( 75_J );
1258 }
1259 }
1260
1261 if( has_bionic( bio_reactoroverride ) && powered_reactor ) {
1262 if( get_bionic_state( bio_reactoroverride ).powered ) {
1263 int current_fuel_stock = std::stoi( get_value( plut_cell.str() ) );
1264
1265 current_fuel_stock -= 50;
1266
1267 set_value( plut_cell.str(), std::to_string( current_fuel_stock ) );
1268 update_fuel_storage( plut_cell );
1269
1270 mod_power_level( 40_kJ );
1271 mod_rad( 2 );
1272 }
1273 }
1274 }
1275}
int get_fuel_type_available(const itype_id &fuel) const
Return available space to store specified fuel.
Definition: character.cpp:2026
static const bionic_id bio_geiger("bio_geiger")
static const std::string flag_RAD_RESIST("RAD_RESIST")
static const bionic_id bio_reactoroverride("bio_reactoroverride")
static const bionic_id bio_reactor("bio_reactor")
static const trait_id trait_RADIOGENIC("RADIOGENIC")
static const bionic_id bio_advreactor("bio_advreactor")

References _, Creature::add_msg_if_player(), bio_advreactor, bio_geiger, bio_reactor, bio_reactoroverride, flag_RAD_RESIST(), get_bionic_state(), stomach_contents::get_calories(), get_fuel_type_available(), get_healthy_mod(), get_map(), get_rad(), Creature::get_value(), has_bionic(), has_trait(), healall(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), hurtall(), in_sleep_state(), irradiate(), is_rad_immune(), is_wearing_power_armor(), leak_level(), m_warning, mod_power_level(), mod_rad(), mutate(), calendar::once_every(), one_in(), pos(), rng(), set_healthy_mod(), set_rad(), Creature::set_value(), stomach, string_id< T >::str(), to_string(), trait_RADIOACTIVE1, trait_RADIOACTIVE2, trait_RADIOACTIVE3, trait_RADIOGENIC, item::typeId(), update_fuel_storage(), vomit(), worn_with_flag(), and x_in_y().

Referenced by suffer().

◆ suffer_from_schizophrenia()

void Character::suffer_from_schizophrenia ( )
private

Definition at line 424 of file suffer.cpp.

425{
426 std::string i_name_w;
427 item &weapon = primary_weapon();
428 if( !weapon.is_null() ) {
429 i_name_w = weapon.has_var( "item_label" ) ? weapon.get_var( "item_label" ) :
430 //~ %1$s: weapon name
431 string_format( _( "your %1$s" ), weapon.type_name() );
432 }
433 // Start with the effects that both NPCs and avatars can suffer from
434 // Delusions
435 if( one_turn_in( 8_hours ) ) {
436 if( rng( 1, 20 ) > 5 ) { // 75% chance
437 const translation snip = SNIPPET.random_from_category( "schizo_delusion_paranoid" ).value_or(
438 translation() );
439 add_msg_if_player( m_warning, "%s", snip );
440 add_morale( MORALE_FEELING_BAD, -20, -100 );
441 } else { // 25% chance
442 const translation snip = SNIPPET.random_from_category( "schizo_delusion_grandiose" ).value_or(
443 translation() );
444 add_msg_if_player( m_good, "%s", snip );
446 }
447 return;
448 }
449 // Formication
450 if( one_turn_in( 6_hours ) ) {
451 const translation snip = SNIPPET.random_from_category( "schizo_formication" ).value_or(
452 translation() );
453 body_part bp = random_body_part( true );
454 add_effect( effect_formication, 45_minutes, bp );
455 add_msg_if_player( m_bad, "%s", snip );
456 return;
457 }
458 // Numbness
459 if( one_turn_in( 4_hours ) ) {
460 add_msg_if_player( m_bad, _( "You suddenly feel so numb…" ) );
461 mod_painkiller( 25 );
462 return;
463 }
464 // Hallucination
465 if( one_turn_in( 6_hours ) ) {
466 add_effect( effect_hallu, 6_hours );
467 return;
468 }
469 // Visuals
470 if( one_turn_in( 2_hours ) ) {
471 add_effect( effect_visuals, rng( 15_turns, 60_turns ) );
472 return;
473 }
474 // Shaking
475 if( !has_effect( effect_valium ) && one_turn_in( 4_hours ) ) {
476 add_msg_player_or_npc( m_bad, _( "You start to shake uncontrollably." ),
477 _( "<npcname> starts to shake uncontrollably." ) );
478 add_effect( effect_shakes, rng( 2_minutes, 5_minutes ) );
479 return;
480 }
481 // Shout
482 if( one_turn_in( 4_hours ) ) {
483 shout( SNIPPET.random_from_category( "schizo_self_shout" ).value_or( translation() ).translated() );
484 return;
485 }
486 // Drop weapon
487 if( one_turn_in( 2_days ) && !weapon.is_null() ) {
488 const translation snip = SNIPPET.random_from_category( "schizo_weapon_drop" ).value_or(
489 translation() );
490 std::string str = string_format( snip, i_name_w );
491 str[0] = toupper( str[0] );
492
493 add_msg_if_player( m_bad, "%s", str );
494 item_location loc( *this, &weapon );
495 drop( loc, pos() );
496 return;
497 }
498 // Talk to self
499 if( one_turn_in( 4_hours ) ) {
500 const translation snip = SNIPPET.random_from_category( "schizo_self_talk" ).value_or(
501 translation() );
502 add_msg( _( "%1$s says: \"%2$s\"" ), name, snip );
503 return;
504 }
505
506 // effects of this point are entirely internal, so NPCs can't suffer from them
507 if( is_npc() ) {
508 return;
509 }
510 // Sound
511 if( one_turn_in( 4_hours ) ) {
512 sound_hallu();
513 }
514 // Follower turns hostile
515 if( one_turn_in( 4_hours ) ) {
516 std::vector<shared_ptr_fast<npc>> followers = overmap_buffer.get_npcs_near_player( 12 );
517
518 std::string who_gets_angry = name;
519 if( !followers.empty() ) {
520 who_gets_angry = random_entry_ref( followers )->name;
521 }
522 add_msg_if_player( m_bad, _( "%1$s gets angry!" ), who_gets_angry );
523 return;
524 }
525
526 // Monster dies
527 if( one_turn_in( 6_hours ) ) {
528 // TODO: move to monster group json
529 static const std::array<mtype_id, 5> monsters = { {
531 }
532 };
533 add_msg_if_player( _( "%s dies!" ), random_entry_ref( monsters )->nname() );
534 return;
535 }
536
537 // Limb Breaks
538 if( one_turn_in( 4_hours ) ) {
539 const translation snip = SNIPPET.random_from_category( "broken_limb" ).value_or( translation() );
540 add_msg_if_player( m_bad, "%s", snip );
541 return;
542 }
543
544 // NPC chat
545 if( one_turn_in( 4_hours ) ) {
546 std::string i_name = Name::generate( one_in( 2 ) );
547
548 std::string i_talk = SNIPPET.expand( SNIPPET.random_from_category( "<lets_talk>" ).value_or(
549 translation() ).translated() );
550 parse_tags( i_talk, *this, *this );
551
552 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name, i_talk );
553 return;
554 }
555
556 // Skill raise
557 if( one_turn_in( 12_hours ) ) {
558 skill_id raised_skill = Skill::random_skill();
559 add_msg_if_player( m_good, _( "You increase %1$s to level %2$d." ), raised_skill.obj().name(),
560 get_skill_level( raised_skill ) + 1 );
561 return;
562 }
563
564 // Talking weapon
565 if( !weapon.is_null() ) {
566 // If player has a weapon, picks a message from said weapon
567 // Weapon tells player to kill a monster if any are nearby
568 // Weapon is concerned for player if bleeding
569 // Weapon is concerned for itself if damaged
570 // Otherwise random chit-chat
571 std::vector<weak_ptr_fast<monster>> mons = g->all_monsters().items;
572
573 std::string i_talk_w;
574 bool does_talk = false;
575 if( !mons.empty() && one_turn_in( 12_minutes ) ) {
576 std::vector<std::string> seen_mons;
577 for( weak_ptr_fast<monster> &n : mons ) {
578 if( sees( *n.lock() ) ) {
579 seen_mons.emplace_back( n.lock()->get_name() );
580 }
581 }
582 if( !seen_mons.empty() ) {
583 const translation talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_monster" ).value_or(
584 translation() );
585 i_talk_w = string_format( talk_w, random_entry_ref( seen_mons ) );
586 does_talk = true;
587 }
588 }
589 if( !does_talk && has_effect( effect_bleed ) && one_turn_in( 5_minutes ) ) {
590 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_bleeding" ).value_or(
591 translation() ).translated();
592 does_talk = true;
593 } else if( weapon.damage() >= weapon.max_damage() / 3 && one_turn_in( 1_hours ) ) {
594 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_damaged" ).value_or(
595 translation() ).translated();
596 does_talk = true;
597 } else if( one_turn_in( 4_hours ) ) {
598 i_talk_w = SNIPPET.random_from_category( "schizo_weapon_talk_misc" ).value_or(
599 translation() ).translated();
600 does_talk = true;
601 }
602 if( does_talk ) {
603 add_msg_if_player( _( "%1$s says: \"%2$s\"" ), i_name_w, i_talk_w );
604 return;
605 }
606 }
607}
static skill_id random_skill()
Definition: skill.cpp:205
double get_var(const std::string &name, double default_value) const
Definition: item.cpp:1035
int max_damage() const
Maximum amount of damage to an item (state before destroyed)
Definition: item.cpp:6226
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1080
int damage() const
How much damage has the item sustained?
Definition: item.cpp:701
std::vector< shared_ptr_fast< npc > > get_npcs_near_player(int radius)
Same as get_npcs_near(int,int,int,int) but uses player position as center.
std::string expand(const std::string &str) const
Expand the string by recursively replacing tags in angle brackets (<>) with random snippets from the ...
std::weak_ptr< T > weak_ptr_fast
Definition: memory_fast.h:17
void parse_tags(std::string &phrase, const Character &u, const Character &me, const itype_id &item_type=itype_id::NULL_ID())
Definition: npctalk.cpp:1618
static const mtype_id mon_zombie_cop("mon_zombie_cop")
static const efftype_id effect_hallu("hallu")
static const mtype_id mon_zombie_fireman("mon_zombie_fireman")
static const mtype_id mon_zombie_fat("mon_zombie_fat")
static const mtype_id mon_zombie_soldier("mon_zombie_soldier")
static const mtype_id mon_zombie("mon_zombie")
static const efftype_id effect_valium("valium")

References _, Creature::add_effect(), add_morale(), add_msg(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), item::damage(), drop(), effect_bleed, effect_formication, effect_hallu, effect_shakes, effect_valium, effect_visuals, snippet_library::expand(), g, Name::generate(), overmapbuffer::get_npcs_near_player(), get_skill_level(), item::get_var(), Creature::has_effect(), item::has_var(), Creature::is_npc(), item::is_null(), m_bad, m_good, m_warning, item::max_damage(), mod_painkiller(), mon_zombie, mon_zombie_cop, mon_zombie_fat, mon_zombie_fireman, mon_zombie_soldier, MORALE_FEELING_BAD, MORALE_FEELING_GOOD, name, Skill::name(), string_id< T >::obj(), one_in(), one_turn_in(), overmap_buffer, parse_tags(), pos(), primary_weapon(), random_body_part(), random_entry_ref(), snippet_library::random_from_category(), Skill::random_skill(), rng(), sees(), shout(), SNIPPET, sound_hallu(), string_format(), and item::type_name().

Referenced by suffer_while_awake().

◆ suffer_from_stimulants()

void Character::suffer_from_stimulants ( int  current_stim)
private

Definition at line 1393 of file suffer.cpp.

1394{
1395 // Stim +250 kills
1396 if( current_stim > 210 ) {
1397 if( one_turn_in( 2_minutes ) && !has_effect( effect_downed ) ) {
1398 add_msg_if_player( m_bad, _( "Your muscles spasm!" ) );
1399 if( !has_effect( effect_downed ) ) {
1400 add_msg_if_player( m_bad, _( "You fall to the ground!" ) );
1401 add_effect( effect_downed, rng( 6_turns, 20_turns ) );
1402 }
1403 }
1404 }
1405 if( current_stim > 110 ) {
1406 if( !has_effect( effect_shakes ) && calendar::once_every( 10_minutes ) ) {
1407 add_msg_if_player( _( "You shake uncontrollably." ) );
1408 add_effect( effect_shakes, 15_minutes + 1_turns );
1409 }
1410 }
1411 if( current_stim > 75 ) {
1412 if( calendar::once_every( 5_minutes ) && !has_effect( effect_nausea ) ) {
1413 add_msg_if_player( _( "You feel nauseous…" ) );
1414 add_effect( effect_nausea, 5_minutes );
1415 }
1416 }
1417
1418 //stim -200 or painkillers 240 kills
1419 if( current_stim < -160 || get_painkiller() > 200 ) {
1420 if( one_turn_in( 3_minutes ) && !in_sleep_state() ) {
1421 add_msg_if_player( m_bad, _( "You black out!" ) );
1422 const time_duration dur = rng( 30_minutes, 60_minutes );
1423 add_effect( effect_downed, dur );
1424 fall_asleep( dur );
1425 }
1426 }
1427 if( current_stim < -60 || get_painkiller() > 130 ) {
1428 if( calendar::once_every( 10_minutes ) ) {
1429 add_msg_if_player( m_warning, _( "You feel tired…" ) );
1430 mod_fatigue( rng( 1, 2 ) );
1431 }
1432 }
1433}
static const efftype_id effect_nausea("nausea")

References _, Creature::add_effect(), Creature::add_msg_if_player(), effect_downed, effect_nausea, effect_shakes, fall_asleep(), get_painkiller(), Creature::has_effect(), in_sleep_state(), m_bad, m_warning, mod_fatigue(), calendar::once_every(), one_turn_in(), and rng().

Referenced by suffer().

◆ suffer_from_sunburn()

void Character::suffer_from_sunburn ( )
private

Definition at line 889 of file suffer.cpp.

890{
892 return;
893 }
894
895 std::string sunlight_effect;
897 // Albinism and datura have the same effects, once per minute on average
898 if( !one_turn_in( 1_minutes ) ) {
899 return;
900 }
901 sunlight_effect = _( "The sunlight is really irritating" );
902 } else if( has_trait( trait_SUNBURN ) ) {
903 // Sunburn effects occur about 3 times per minute
904 if( !one_turn_in( 20_seconds ) ) {
905 return;
906 }
907 sunlight_effect = _( "The sunlight burns" );
908 }
909
910 // Sunglasses can keep the sun off the eyes.
911 if( !has_bionic( bio_sunglasses ) &&
912 !( wearing_something_on( bodypart_id( "eyes" ) ) &&
914 add_msg_if_player( m_bad, _( "%s your eyes." ), sunlight_effect );
915 // Pain (1/60) or loss of focus (59/60)
916 if( one_turn_in( 1_minutes ) ) {
917 mod_pain( 1 );
918 } else {
919 focus_pool --;
920 }
921 }
922 // Umbrellas can keep the sun off the skin
923 if( primary_weapon().has_flag( "RAIN_PROTECT" ) ) {
924 return;
925 }
926
927 std::map<bodypart_id, float> bp_exposure = bodypart_exposure();
928
929 // Minimum exposure threshold for pain
930 const float MIN_EXPOSURE = 0.01f;
931 // Count how many body parts are above the threshold
932 int count_affected_bp = 0;
933 // Get the most exposed body part, and how exposed it is. This is to tell the player what body
934 // part is most irritated by sun, so they know what needs to be covered up better.
935 bodypart_id most_exposed_bp;
936 float max_exposure = 0.0f;
937 // Check each bodypart with exposure above the minimum
938 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
939 const float exposure = bp_exp.second;
940 // Skip minimally-exposed parts, and skip the eyes (handled by sunglasses)
941 if( exposure <= MIN_EXPOSURE || bp_exp.first == bodypart_id( "eyes" ) ) {
942 continue;
943 }
944 ++count_affected_bp;
945 if( exposure > max_exposure ) {
946 max_exposure = exposure;
947 most_exposed_bp = bp_exp.first;
948 }
949 }
950
951 // If all body parts are protected, there is no suffering
952 if( count_affected_bp == 0 || !most_exposed_bp ) {
953 return;
954 }
955
956 // Check if both arms/legs are affected
957 int count_limbs = 1;
958 const bodypart_id &other_bp = most_exposed_bp->opposite_part;
959 const bodypart_id &other_bp_rev = other_bp->opposite_part;
960 // If these are different, we have a left/right part like a leg or arm.
961 // If same, it's a central body part with no opposite, like head or torso.
962 // Only used to generate a simpler message when both arms or both legs are affected.
963 if( other_bp != other_bp_rev ) {
964 const auto found = bp_exposure.find( other_bp );
965 // Is opposite part exposed?
966 if( found != bp_exposure.end() && found->second > MIN_EXPOSURE ) {
967 ++count_limbs;
968 }
969 }
970 // Get singular or plural body part name; append "and other body parts" if appropriate
971 std::string bp_name = body_part_name( most_exposed_bp, count_limbs );
972 if( count_affected_bp == count_limbs ) {
973 add_msg_if_player( m_bad, _( "%s your %s." ), sunlight_effect, bp_name );
974 } else {
975 add_msg_if_player( m_bad, _( "%s your %s and other body parts." ), sunlight_effect,
976 bp_name );
977 }
978
979 // Wake up from skin irritation/burning
980 if( has_effect( effect_sleep ) ) {
981 wake_up();
982 }
983
984 // Solar Sensitivity (SUNBURN) trait causes injury to exposed parts
985 if( has_trait( trait_SUNBURN ) ) {
986 mod_pain( 1 );
987 // Check exposure of all body parts
988 for( const std::pair<const bodypart_id, float> &bp_exp : bp_exposure ) {
989 const bodypart_id &this_part = bp_exp.first;
990 const float exposure = bp_exp.second;
991 // Skip parts with adequate protection
992 if( exposure <= MIN_EXPOSURE ) {
993 continue;
994 }
995 // Don't damage eyes directly, since it takes from head HP (in other words, your head
996 // won't be destroyed if only your eyes are exposed).
997 if( this_part == bodypart_id( "eyes" ) ) {
998 continue;
999 }
1000 // Exposure percentage determines likelihood of injury
1001 // 10% exposure is 10% chance of injury, naked = 100% chance
1002 if( x_in_y( exposure, 1.0 ) ) {
1003 // Because hands and feet share an HP pool with arms and legs, and the mouth shares
1004 // an HP pool with the head, those parts take an unfair share of damage in relation
1005 // to the torso, which only has one part. Increase torso damage to balance this.
1006 if( this_part == bodypart_id( "torso" ) ) {
1007 apply_damage( nullptr, this_part, 2 );
1008 } else {
1009 apply_damage( nullptr, this_part, 1 );
1010 }
1011 }
1012 }
1013 } else {
1014 // Albinism/datura causes pain (1/60) or focus loss (59/60)
1015 if( one_turn_in( 1_minutes ) ) {
1016 mod_pain( 1 );
1017 } else {
1018 focus_pool --;
1019 }
1020 }
1021}
std::map< bodypart_id, float > bodypart_exposure()
Map body parts to their total exposure, from 0.0 (fully covered) to 1.0 (buck naked).
Definition: suffer.cpp:862
static const trait_id trait_ALBINO("ALBINO")
static const std::string flag_BLIND("BLIND")
static const trait_id trait_SUNBURN("SUNBURN")
static const std::string flag_SUN_GLASSES("SUN_GLASSES")
static const bionic_id bio_sunglasses("bio_sunglasses")

References _, Creature::add_msg_if_player(), apply_damage(), bio_sunglasses, body_part_name(), bodypart_exposure(), effect_datura, effect_sleep, flag_BLIND(), flag_SUN_GLASSES(), focus_pool, has_bionic(), Creature::has_effect(), Creature::has_flag(), has_trait(), m_bad, mod_pain(), one_turn_in(), primary_weapon(), trait_ALBINO, trait_SUNBURN, wake_up(), wearing_something_on(), worn_with_flag(), and x_in_y().

Referenced by suffer_in_sunlight().

◆ suffer_in_sunlight()

void Character::suffer_in_sunlight ( )
private

Definition at line 797 of file suffer.cpp.

798{
799 double sleeve_factor = armwear_factor();
800 const bool has_hat = wearing_something_on( bodypart_id( "head" ) );
801 const bool leafy = has_trait( trait_LEAVES ) || has_trait( trait_LEAVES2 ) ||
803 const bool leafier = has_trait( trait_LEAVES2 ) || has_trait( trait_LEAVES3 );
804 const bool leafiest = has_trait( trait_LEAVES3 );
805 int sunlight_nutrition = 0;
806 if( leafy && get_map().is_outside( pos() ) && ( g->light_level( pos().z ) >= 40 ) ) {
807 const float weather_factor = ( get_weather().weather_id->sun_intensity >=
808 sun_intensity_type::normal ) ? 1.0 : 0.5;
809 const int player_local_temp = get_weather().get_temperature( pos() );
810 int flux = ( player_local_temp - 65 ) / 2;
811 if( !has_hat ) {
812 sunlight_nutrition += ( 100 + flux ) * weather_factor;
813 }
814 if( leafier ) {
815 int rate = ( ( 100 * sleeve_factor ) + flux ) * 2;
816 sunlight_nutrition += ( rate * ( leafiest ? 2 : 1 ) ) * weather_factor;
817 }
818 }
819
820 if( x_in_y( sunlight_nutrition, 18000 ) ) {
821 vitamin_mod( vitamin_id( "vitA" ), 1, true );
822 vitamin_mod( vitamin_id( "vitC" ), 1, true );
823 }
824
825 if( x_in_y( sunlight_nutrition, 12000 ) ) {
826 mod_stored_kcal( 10 );
827 stomach.ate();
828 }
829
830 if( !g->is_in_sunlight( pos() ) ) {
831 return;
832 }
833
836 }
837
839 get_weather().weather_id->sun_intensity >= sun_intensity_type::high ) {
840 mod_str_bonus( -1 );
841 mod_dex_bonus( -1 );
842 add_miss_reason( _( "The sunlight distracts you." ), 1 );
843 mod_int_bonus( -1 );
844 mod_per_bonus( -1 );
845 }
846 if( has_trait( trait_TROGLO2 ) ) {
847 mod_str_bonus( -1 );
848 mod_dex_bonus( -1 );
849 add_miss_reason( _( "The sunlight distracts you." ), 1 );
850 mod_int_bonus( -1 );
851 mod_per_bonus( -1 );
852 }
853 if( has_trait( trait_TROGLO3 ) ) {
854 mod_str_bonus( -4 );
855 mod_dex_bonus( -4 );
856 add_miss_reason( _( "You can't stand the sunlight!" ), 4 );
857 mod_int_bonus( -4 );
858 mod_per_bonus( -4 );
859 }
860}
void suffer_from_sunburn()
Definition: suffer.cpp:889
double armwear_factor() const
Same as footwear factor, but for arms.
Definition: character.cpp:8930
weather_type_id weather_id
Definition: weather.h:193
sun_intensity_type sun_intensity
Definition: weather_type.h:121
static const trait_id trait_LEAVES("LEAVES")
static const trait_id trait_TROGLO3("TROGLO3")
static const trait_id trait_LEAVES2("LEAVES2")
static const trait_id trait_TROGLO("TROGLO")
static const trait_id trait_TROGLO2("TROGLO2")
static const trait_id trait_LEAVES3("LEAVES3")

References _, add_miss_reason(), armwear_factor(), stomach_contents::ate(), effect_datura, g, get_map(), weather_manager::get_temperature(), get_weather(), Creature::has_effect(), has_trait(), high, mod_dex_bonus(), mod_int_bonus(), mod_per_bonus(), mod_stored_kcal(), mod_str_bonus(), normal, pos(), stomach, suffer_from_sunburn(), weather_type::sun_intensity, trait_ALBINO, trait_LEAVES, trait_LEAVES2, trait_LEAVES3, trait_SUNBURN, trait_TROGLO, trait_TROGLO2, trait_TROGLO3, vitamin_mod(), wearing_something_on(), weather_manager::weather_id, and x_in_y().

Referenced by suffer().

◆ suffer_mutation_power()

void Character::suffer_mutation_power ( const mutation_branch mdata,
char_trait_data tdata 
)
private

Definition at line 195 of file suffer.cpp.

196{
197 if( tdata.powered && tdata.charge > 0 ) {
198 // Already-on units just lose a bit of charge
199 tdata.charge--;
200 } else {
201 // Not-on units, or those with zero charge, have to pay the power cost
202 if( mdata.cooldown > 0 ) {
203 tdata.powered = true;
204 tdata.charge = mdata.cooldown - 1;
205 }
206 if( mdata.hunger ) {
207 // does not directly modify hunger, but burns kcal
208 mod_stored_nutr( mdata.cost );
211 _( "You're too malnourished to keep your %s going." ),
212 mdata.name() );
213 tdata.powered = false;
214 }
215 }
216 if( mdata.thirst ) {
217 mod_thirst( mdata.cost );
218 // Well into Dehydrated
221 _( "You're too dehydrated to keep your %s going." ),
222 mdata.name() );
223 tdata.powered = false;
224 }
225 }
226 if( mdata.fatigue ) {
227 mod_fatigue( mdata.cost );
228 // Exhausted
231 _( "You're too exhausted to keep your %s going." ),
232 mdata.name() );
233 tdata.powered = false;
234 }
235 }
236 if( !tdata.powered ) {
237 apply_mods( mdata.id, false );
238 }
239 }
240}
constexpr float underweight

References _, Creature::add_msg_if_player(), apply_mods(), bmi(), char_trait_data::charge, mutation_branch::cooldown, mutation_branch::cost, dehydrated, exhausted, mutation_branch::fatigue, get_fatigue(), get_thirst(), mutation_branch::hunger, mutation_branch::id, m_warning, mod_fatigue(), mod_stored_nutr(), mod_thirst(), mutation_branch::name(), char_trait_data::powered, mutation_branch::thirst, and character_weight_category::underweight.

Referenced by suffer().

◆ suffer_water_damage()

void Character::suffer_water_damage ( const mutation_branch mdata)
private

suffer() subcalls

Definition at line 175 of file suffer.cpp.

176{
177 for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
178 const float wetness_percentage = static_cast<float>( body_wetness[elem.first->token] ) /
179 drench_capacity[elem.first->token];
180 const int dmg = mdata.weakness_to_water * wetness_percentage;
181 if( dmg > 0 ) {
182 apply_damage( nullptr, elem.first, dmg );
183 add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the water." ),
184 _( "<npcname>'s %s is damaged by the water." ),
185 body_part_name( elem.first ) );
186 } else if( dmg < 0 && elem.second.is_at_max_hp() ) {
187 heal( elem.first, std::abs( dmg ) );
188 add_msg_player_or_npc( m_good, _( "Your %s is healed by the water." ),
189 _( "<npcname>'s %s is healed by the water." ),
190 body_part_name( elem.first ) );
191 }
192 }
193}
int weakness_to_water
maximum damage dealt by water every minute when wet.
Definition: mutation.h:170

References _, Creature::add_msg_player_or_npc(), apply_damage(), body_part_name(), body_wetness, drench_capacity, Creature::get_body(), heal(), m_bad, m_good, and mutation_branch::weakness_to_water.

Referenced by suffer().

◆ suffer_while_awake()

void Character::suffer_while_awake ( int  current_stim)
private

Definition at line 292 of file suffer.cpp.

293{
295 ( weight_carried() > 4 * weight_capacity() ) ) {
296 if( has_effect( effect_downed ) ) {
297 add_effect( effect_downed, 1_turns, num_bp, 0 );
298 } else {
299 add_effect( effect_downed, 2_turns, num_bp, 0 );
300 }
301 }
304 }
308 }
309
311 if( one_turn_in( 8_hours ) ) {
313 _( "You're suddenly overcome with the urge to sleep and you pass out." ),
314 _( "<npcname>'s suddenly passes out." ) );
315 fall_asleep( 20_minutes );
316 }
317 }
318
320 if( current_stim > 50 && one_in( to_turns<int>( 30_minutes ) - ( current_stim * 6 ) ) ) {
321 add_effect( effect_shakes, 30_minutes + 1_turns * current_stim );
322 } else if( ( get_kcal_percent() < 0.95f ) &&
323 one_turn_in( 60_minutes - 1_seconds * ( max_stored_kcal() - get_stored_kcal() ) ) ) {
324 add_effect( effect_shakes, 40_minutes );
325 }
326 }
327
328 if( has_trait( trait_MOODSWINGS ) && one_turn_in( 6_hours ) ) {
329 if( rng( 1, 20 ) > 9 ) {
330 // 55% chance
331 add_morale( MORALE_MOODSWING, -100, -500 );
332 } else {
333 // 45% chance
334 add_morale( MORALE_MOODSWING, 100, 500 );
335 }
336 }
337
338 if( has_trait( trait_VOMITOUS ) && one_turn_in( 7_hours ) ) {
339 vomit();
340 }
341
342 if( has_trait( trait_SHOUT1 ) && one_turn_in( 6_hours ) ) {
343 shout();
344 }
345 if( has_trait( trait_SHOUT2 ) && one_turn_in( 4_hours ) ) {
346 shout();
347 }
348 if( has_trait( trait_SHOUT3 ) && one_turn_in( 3_hours ) ) {
349 shout();
350 }
351 if( has_trait( trait_M_SPORES ) && one_turn_in( 4_hours ) ) {
352 spores();
353 }
354 if( has_trait( trait_M_BLOSSOMS ) && one_turn_in( 3_hours ) ) {
355 blossoms();
356 }
357}
void suffer_from_chemimbalance()
Definition: suffer.cpp:359
void suffer_from_schizophrenia()
Definition: suffer.cpp:424
const morale_type MORALE_MOODSWING("morale_moodswing")
static const trait_id trait_JITTERY("JITTERY")
static const trait_id trait_SHOUT1("SHOUT1")
static const trait_id trait_NARCOLEPTIC("NARCOLEPTIC")
static const efftype_id effect_took_thorazine("took_thorazine")
static const trait_id trait_SHOUT2("SHOUT2")
static const trait_id trait_VOMITOUS("VOMITOUS")
static const trait_id trait_DEBUG_STORAGE("DEBUG_STORAGE")
static const trait_id trait_CHEMIMBALANCE("CHEMIMBALANCE")
static const trait_id trait_M_BLOSSOMS("M_BLOSSOMS")
static const trait_id trait_SHOUT3("SHOUT3")
static const trait_id trait_SCHIZOPHRENIC("SCHIZOPHRENIC")
static const trait_id trait_M_SPORES("M_SPORES")
static const trait_id trait_MOODSWINGS("MOODSWINGS")

References _, Creature::add_effect(), add_morale(), Creature::add_msg_player_or_npc(), AEP_SCHIZO, blossoms(), effect_downed, effect_feral_killed_recently, effect_shakes, effect_took_thorazine, fall_asleep(), get_kcal_percent(), get_stored_kcal(), has_artifact_with(), Creature::has_effect(), has_trait(), m_bad, max_stored_kcal(), MORALE_MOODSWING, num_bp, one_in(), one_turn_in(), rng(), shout(), spores(), suffer_from_chemimbalance(), suffer_from_schizophrenia(), trait_CHEMIMBALANCE, trait_DEBUG_STORAGE, trait_JITTERY, trait_M_BLOSSOMS, trait_M_SPORES, trait_MOODSWINGS, trait_NARCOLEPTIC, trait_SCHIZOPHRENIC, trait_SHOUT1, trait_SHOUT2, trait_SHOUT3, trait_VOMITOUS, vomit(), weight_capacity(), and weight_carried().

Referenced by suffer().

◆ suffer_while_underwater()

void Character::suffer_while_underwater ( )
private

Definition at line 242 of file suffer.cpp.

243{
245 oxygen--;
246 }
247 if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) {
248 oxygen += 12;
249 }
250 if( oxygen <= 5 ) {
252 oxygen += 5;
254 } else {
255 add_msg_if_player( m_bad, _( "You're drowning!" ) );
256 apply_damage( nullptr, bodypart_id( "torso" ), rng( 1, 4 ) );
257 }
258 }
259 if( has_trait( trait_FRESHWATEROSMOSIS ) && !get_map().has_flag_ter( "SALT_WATER", pos() ) &&
261 mod_thirst( -1 );
262 }
263}
static const trait_id trait_FRESHWATEROSMOSIS("FRESHWATEROSMOSIS")
static const trait_id trait_GILLS_CEPH("GILLS_CEPH")
static const trait_id trait_GILLS("GILLS")

References _, Creature::add_msg_if_player(), apply_damage(), bio_gills, get_map(), get_power_level(), get_thirst(), has_bionic(), has_trait(), m_bad, mod_power_level(), mod_thirst(), oxygen, pos(), bionic_data::power_trigger, rng(), trait_FRESHWATEROSMOSIS, trait_GILLS, trait_GILLS_CEPH, turgid, and worn_with_flag().

Referenced by suffer().

◆ suffer_without_sleep()

void Character::suffer_without_sleep ( int  sleep_deprivation)
private

Definition at line 1435 of file suffer.cpp.

1436{
1437 if( has_effect( effect_meth ) ) {
1438 return;
1439 }
1440 // redo as a snippet?
1442 if( one_turn_in( 50_minutes ) ) {
1443 switch( dice( 1, 4 ) ) {
1444 default:
1445 case 1:
1446 add_msg_player_or_npc( m_warning, _( "You tiredly rub your eyes." ),
1447 _( "<npcname> tiredly rubs their eyes." ) );
1448 break;
1449 case 2:
1450 add_msg_player_or_npc( m_warning, _( "You let out a small yawn." ),
1451 _( "<npcname> lets out a small yawn." ) );
1452 break;
1453 case 3:
1454 add_msg_player_or_npc( m_warning, _( "You stretch your back." ),
1455 _( "<npcname> stretches their back." ) );
1456 break;
1457 case 4:
1458 add_msg_player_or_npc( m_warning, _( "You feel mentally tired." ),
1459 _( "<npcname> lets out a huge yawn." ) );
1460 break;
1461 }
1462 }
1463 }
1464 // Minor discomfort
1466 if( one_turn_in( 75_minutes ) ) {
1467 add_msg_if_player( m_warning, _( "You feel lightheaded for a moment." ) );
1468 moves -= 10;
1469 }
1470 if( one_turn_in( 100_minutes ) ) {
1471 add_msg_if_player( m_warning, _( "Your muscles spasm uncomfortably." ) );
1472 mod_pain( 2 );
1473 }
1474 if( !has_effect( effect_visuals ) && one_turn_in( 150_minutes ) ) {
1475 add_msg_if_player( m_warning, _( "Your vision blurs a little." ) );
1476 add_effect( effect_visuals, rng( 1_minutes, 5_minutes ) );
1477 }
1478 }
1479 // Slight disability
1481 if( one_turn_in( 75_minutes ) ) {
1482 add_msg_if_player( m_bad, _( "Your mind lapses into unawareness briefly." ) );
1483 moves -= rng( 20, 80 );
1484 }
1485 if( one_turn_in( 125_minutes ) ) {
1486 add_msg_if_player( m_bad, _( "Your muscles ache in stressfully unpredictable ways." ) );
1487 mod_pain( rng( 2, 10 ) );
1488 }
1489 if( one_turn_in( 5_hours ) ) {
1490 add_msg_if_player( m_bad, _( "You have a distractingly painful headache." ) );
1491 mod_pain( rng( 10, 25 ) );
1492 }
1493 }
1494 // Major disability, high chance of passing out also relevant
1496 if( !has_effect( effect_nausea ) && one_turn_in( 500_minutes ) ) {
1497 add_msg_if_player( m_bad, _( "You feel heartburn and an acid taste in your mouth." ) );
1498 mod_pain( 5 );
1499 add_effect( effect_nausea, rng( 5_minutes, 30_minutes ) );
1500 }
1501 if( one_turn_in( 5_hours ) ) {
1502 add_msg_if_player( m_bad, _( "Your mind is so tired that you feel you can't trust "
1503 "your eyes anymore." ) );
1504 add_effect( effect_hallu, rng( 5_minutes, 60_minutes ) );
1505 }
1506 if( !has_effect( effect_shakes ) && one_turn_in( 425_minutes ) ) {
1507 add_msg_if_player( m_bad, _( "Your muscles spasm uncontrollably, and you have "
1508 "trouble keeping your balance." ) );
1509 add_effect( effect_shakes, 15_minutes );
1510 } else if( has_effect( effect_shakes ) && one_turn_in( 75_seconds ) ) {
1511 moves -= 10;
1512 add_msg_player_or_npc( m_warning, _( "Your shaking legs make you stumble." ),
1513 _( "<npcname> stumbles." ) );
1514 if( !has_effect( effect_downed ) && one_in( 10 ) ) {
1515 add_msg_player_or_npc( m_bad, _( "You fall over!" ), _( "<npcname> falls over!" ) );
1516 add_effect( effect_downed, rng( 3_turns, 10_turns ) );
1517 }
1518 }
1519 }
1520}
static const efftype_id effect_meth("meth")

References _, Creature::add_effect(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), dice(), effect_downed, effect_hallu, effect_meth, effect_nausea, effect_shakes, effect_visuals, harmless, Creature::has_effect(), m_bad, m_warning, major, minor, mod_pain(), Creature::moves, one_in(), one_turn_in(), rng(), serious, and sleep_deprivation.

Referenced by suffer().

◆ swim_speed()

int Character::swim_speed ( ) const

Returns the player's speed for swimming across water tiles.

Strength increases swim speed bonus from PAWS Strength increases swim speed bonus from PAWS_LARGE Strength increases swim speed bonus from swim_fins Strength increases swim speed bonus from WEBBED Swimming increases swim speed Strength increases swim speed Dexterity increases swim speed

Definition at line 817 of file character.cpp.

818{
819 int ret;
820 if( is_mounted() ) {
821 monster *mon = mounted_creature.get();
822 // no difference in swim speed by monster type yet.
823 // TODO: difference in swim speed by monster type.
824 // No monsters are currently mountable and can swim, though mods may allow this.
825 if( mon->swims() ) {
826 ret = 25;
827 ret += get_weight() / 120_gram - 50 * mon->get_size();
828 return ret;
829 }
830 }
831 const auto usable = exclusive_flag_coverage( "ALLOWS_NATURAL_ATTACKS" );
832 float hand_bonus_mult = ( usable.test( bp_hand_l ) ? 0.5f : 0.0f ) +
833 ( usable.test( bp_hand_r ) ? 0.5f : 0.0f );
834
835 // base swim speed.
836 ret = ( 440 * mutation_value( "movecost_swim_modifier" ) ) + weight_carried() /
837 ( 60_gram / mutation_value( "movecost_swim_modifier" ) ) - 50 * get_skill_level( skill_swimming );
838 /** @EFFECT_STR increases swim speed bonus from PAWS */
839 if( has_trait( trait_PAWS ) ) {
840 ret -= hand_bonus_mult * ( 20 + str_cur * 3 );
841 }
842 /** @EFFECT_STR increases swim speed bonus from PAWS_LARGE */
843 if( has_trait( trait_PAWS_LARGE ) ) {
844 ret -= hand_bonus_mult * ( 20 + str_cur * 4 );
845 }
846 /** @EFFECT_STR increases swim speed bonus from swim_fins */
847 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) ||
848 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
849 if( worn_with_flag( "FIN", bodypart_id( "foot_l" ) ) &&
850 worn_with_flag( "FIN", bodypart_id( "foot_r" ) ) ) {
851 ret -= ( 15 * str_cur );
852 } else {
853 ret -= ( 15 * str_cur ) / 2;
854 }
855 }
856 /** @EFFECT_STR increases swim speed bonus from WEBBED */
857 if( has_trait( trait_WEBBED ) ) {
858 ret -= hand_bonus_mult * ( 60 + str_cur * 5 );
859 }
860 /** @EFFECT_SWIMMING increases swim speed */
861 ret += ( 50 - get_skill_level( skill_swimming ) * 2 ) * ( ( encumb( bp_leg_l ) + encumb(
862 bp_leg_r ) ) / 10 );
863 ret += ( 80 - get_skill_level( skill_swimming ) * 3 ) * ( encumb( bp_torso ) / 10 );
864 if( get_skill_level( skill_swimming ) < 10 ) {
865 for( auto &i : worn ) {
866 ret += i.volume() / 125_ml * ( 10 - get_skill_level( skill_swimming ) );
867 }
868 }
869 /** @EFFECT_STR increases swim speed */
870
871 /** @EFFECT_DEX increases swim speed */
872 ret -= str_cur * 6 + dex_cur * 4;
873 if( worn_with_flag( "FLOTATION" ) ) {
874 ret = std::min( ret, 400 );
875 ret = std::max( ret, 200 );
876 }
877 // If (ret > 500), we can not swim; so do not apply the underwater bonus.
878 if( is_underwater() && ret < 500 ) {
879 ret -= 50;
880 }
881
882 // Running movement mode while swimming means faster swim style, like crawlstroke
883 if( move_mode == CMM_RUN ) {
884 ret -= 80;
885 }
886 // Crouching movement mode while swimming means slower swim style, like breaststroke
887 if( move_mode == CMM_CROUCH ) {
888 ret += 50;
889 }
890
891 if( ret < 30 ) {
892 ret = 30;
893 }
894 return ret;
895}
static const skill_id skill_swimming("swimming")
static const trait_id trait_WEBBED("WEBBED")
static const trait_id trait_PAWS_LARGE("PAWS_LARGE")
static const trait_id trait_PAWS("PAWS")
bool swims() const
Definition: monster.cpp:951

References bp_hand_l, bp_hand_r, bp_leg_l, bp_leg_r, bp_torso, CMM_CROUCH, CMM_RUN, dex_cur, encumb(), exclusive_flag_coverage(), monster::get_size(), get_skill_level(), get_weight(), has_trait(), is_mounted(), Creature::is_underwater(), mounted_creature, move_mode, mutation_value(), cata::hash64_detail::ret, skill_swimming, str_cur, monster::swims(), trait_PAWS, trait_PAWS_LARGE, trait_WEBBED, weight_carried(), worn, and worn_with_flag().

Referenced by avatar_action::move(), avatar_action::swim(), and game::vertical_move().

◆ switch_mutations()

void Character::switch_mutations ( const trait_id switched,
const trait_id target,
bool  start_powered 
)

Unset switched mutation and set target mutation instead.

Definition at line 182 of file mutation.cpp.

184{
185 unset_mutation( switched );
186 mutation_loss_effect( switched );
187
188 set_mutation( target );
189 my_mutations[target].powered = start_powered;
190 mutation_effect( target );
191}

References mutation_effect(), mutation_loss_effect(), my_mutations, set_mutation(), and unset_mutation().

Referenced by activate_mutation(), and deactivate_mutation().

◆ symbol()

const std::string & Character::symbol ( ) const
overridevirtual

Implements Creature.

Definition at line 540 of file character.cpp.

541{
542 static const std::string character_symbol( "@" );
543 return character_symbol;
544}

Referenced by anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and avatar::memorize_symbol().

◆ symbol_color()

nc_color Character::symbol_color ( ) const
overridevirtual

Implements Creature.

Definition at line 6048 of file character.cpp.

6049{
6050 nc_color basic = basic_symbol_color();
6051
6052 if( has_effect( effect_downed ) ) {
6053 return hilite( basic );
6054 } else if( has_effect( effect_grabbed ) ) {
6055 return cyan_background( basic );
6056 }
6057
6058 const auto &fields = get_map().field_at( pos() );
6059
6060 // Priority: electricity, fire, acid, gases
6061 bool has_elec = false;
6062 bool has_fire = false;
6063 bool has_acid = false;
6064 bool has_fume = false;
6065 for( const auto &field : fields ) {
6066 has_elec = field.first.obj().has_elec;
6067 if( has_elec ) {
6068 return hilite( basic );
6069 }
6070 has_fire = field.first.obj().has_fire;
6071 has_acid = field.first.obj().has_acid;
6072 has_fume = field.first.obj().has_fume;
6073 }
6074 if( has_fire ) {
6075 return red_background( basic );
6076 }
6077 if( has_acid ) {
6078 return green_background( basic );
6079 }
6080 if( has_fume ) {
6081 return white_background( basic );
6082 }
6083 if( in_sleep_state() ) {
6084 return hilite( basic );
6085 }
6086 return basic;
6087}
nc_color basic_symbol_color() const override
Definition: character.cpp:6018
A variable sized collection of field entries on a given map square.
Definition: field.h:131
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5420
nc_color white_background(const nc_color &c)
Definition: color.cpp:521
nc_color green_background(const nc_color &c)
Definition: color.cpp:527
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
nc_color hilite(const nc_color &c)
Definition: color.cpp:509

References basic_symbol_color(), cyan_background(), effect_downed, effect_grabbed, map::field_at(), get_map(), green_background(), Creature::has_effect(), has_fire(), hilite(), in_sleep_state(), pos(), red_background(), and white_background().

Referenced by overmap_ui::draw_ascii(), anonymous_namespace{animation.cpp}::draw_hit_player_curses(), and game::list_monsters().

◆ takeoff()

bool Character::takeoff ( item it,
std::list< item > *  res = nullptr 
)

Take off an item.

May start an activity.

Parameters
itItem to take off
[out]resIf set, moves resulting item into the list.
Returns
true on success

Definition at line 3046 of file character.cpp.

3047{
3048 const auto ret = can_takeoff( it, res );
3049 if( !ret.success() ) {
3050 add_msg( m_info, "%s", ret.c_str() );
3051 return false;
3052 }
3053
3054 auto iter = std::find_if( worn.begin(), worn.end(), [ &it ]( const item & wit ) {
3055 return &it == &wit;
3056 } );
3057
3058 if( res == nullptr ) {
3060 if( is_npc() || query_yn( _( "No room in inventory for your %s. Drop it?" ),
3061 colorize( it.tname(), it.color_in_inventory() ) ) ) {
3062 item_location loc( *this, &it );
3063 drop( loc, pos() );
3064 return true; // the drop activity ends up taking off the item anyway so shouldn't try to do it again here
3065 } else {
3066 return false;
3067 }
3068 }
3069 iter->on_takeoff( *this );
3071 } else {
3072 iter->on_takeoff( *this );
3073 res->push_back( it );
3074 }
3075
3076 add_msg_player_or_npc( _( "You take off your %s." ),
3077 _( "<npcname> takes off their %s." ),
3078 it.tname() );
3079
3080 // TODO: Make this variable
3081 mod_moves( -250 );
3082 worn.erase( iter );
3083
3086
3087 return true;
3088}
units::volume volume_capacity_reduced_by(const units::volume &mod, const excluded_stacks &without={}) const
Definition: character.cpp:2676
nc_color color_in_inventory() const
Returns the color of the item depending on usefulness for the player character, e....
Definition: item.cpp:4149
units::volume get_storage() const
Returns the storage amount (islot_armor::storage) that this item provides when worn.
Definition: item.cpp:5742

References _, inventory::add_item_keep_invlet(), add_msg(), Creature::add_msg_player_or_npc(), can_takeoff(), item::color_in_inventory(), colorize(), drop(), item::get_storage(), inv, Creature::is_npc(), m_info, Creature::mod_moves(), pos(), query_yn(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::volume(), volume_capacity_reduced_by(), volume_carried(), and worn.

Referenced by npc::adjust_worn(), pickup::obtain_and_tokenize_items(), examine_item_menu::run(), show_armor_layers_ui(), takeoff(), and npc::wear_if_wanted().

◆ temp_corrected_by_climate_control()

int Character::temp_corrected_by_climate_control ( int  temperature) const

Value of the body temperature corrected by climate control.

Definition at line 9569 of file character.cpp.

9570{
9571 const int variation = int( BODYTEMP_NORM * 0.5 );
9572 if( temperature < BODYTEMP_SCORCHING + variation &&
9573 temperature > BODYTEMP_FREEZING - variation ) {
9576 } else if( temperature > BODYTEMP_VERY_HOT ) {
9578 } else if( temperature > BODYTEMP_HOT ) {
9580 } else if( temperature < BODYTEMP_FREEZING ) {
9582 } else if( temperature < BODYTEMP_VERY_COLD ) {
9584 } else if( temperature < BODYTEMP_COLD ) {
9586 }
9587 }
9588 return temperature;
9589}

References BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, and BODYTEMP_VERY_HOT.

Referenced by update_bodytemp().

◆ temp_equalizer()

void Character::temp_equalizer ( const bodypart_id bp1,
const bodypart_id bp2 
)

Equalizes heat between body parts.

Definition at line 5721 of file character.cpp.

5722{
5723 // Body heat is moved around.
5724 // If bp1 is warmer, it will lose heat
5725 int diff = static_cast<int>( ( temp_cur[bp2->token] - temp_cur[bp1->token] ) * 0.001 );
5726 temp_cur[bp1->token] += diff;
5727 temp_cur[bp2->token] -= diff;
5728}

References temp_cur.

Referenced by update_bodytemp().

◆ throw_range()

int Character::throw_range ( const item it) const

Maximum thrown range with a given item, taking all active effects into account.

Strength determines maximum weight that can be thrown Strength increases throwing range, vs item weight (high or low) Strength caps throwing range Throw caps throwing range

Definition at line 6206 of file character.cpp.

6207{
6208 if( it.is_null() ) {
6209 return -1;
6210 }
6211
6212 item tmp = it;
6213
6214 if( tmp.count_by_charges() && tmp.charges > 1 ) {
6215 tmp.charges = 1;
6216 }
6217
6218 /** @EFFECT_STR determines maximum weight that can be thrown */
6219 if( ( tmp.weight() / 113_gram ) > static_cast<int>( str_cur * 15 ) ) {
6220 return 0;
6221 }
6222 // Increases as weight decreases until 150 g, then decreases again
6223 /** @EFFECT_STR increases throwing range, vs item weight (high or low) */
6224 int str_override = str_cur;
6225 if( is_mounted() ) {
6226 auto mons = mounted_creature.get();
6227 str_override = mons->mech_str_addition() != 0 ? mons->mech_str_addition() : str_cur;
6228 }
6229 int ret = ( str_override * 10 ) / ( tmp.weight() >= 150_gram ? tmp.weight() / 113_gram : 10 -
6230 static_cast<int>(
6231 tmp.weight() / 15_gram ) );
6232 ret -= tmp.volume() / 1_liter;
6233 static const std::set<material_id> affected_materials = { material_id( "iron" ), material_id( "steel" ) };
6234 if( has_active_bionic( bio_railgun ) && tmp.made_of_any( affected_materials ) ) {
6235 ret *= 2;
6236 }
6237 if( ret < 1 ) {
6238 return 1;
6239 }
6240 // Cap at double our strength + skill
6241 /** @EFFECT_STR caps throwing range */
6242
6243 /** @EFFECT_THROW caps throwing range */
6244 if( ret > str_override * 3 + get_skill_level( skill_throw ) ) {
6245 return str_override * 3 + get_skill_level( skill_throw );
6246 }
6247
6248 return ret;
6249}
static const bionic_id bio_railgun("bio_railgun")
static const skill_id skill_throw("throw")

References bio_railgun, item::charges, item::count_by_charges(), get_skill_level(), has_active_bionic(), is_mounted(), item::is_null(), item::made_of_any(), mounted_creature, cata::hash64_detail::ret, skill_throw, str_cur, item::volume(), and item::weight().

Referenced by npc::alt_attack(), target_handler::mode_throw(), and avatar_action::plthrow().

◆ toggle_trait()

void Character::toggle_trait ( const trait_id trait_)

Toggles a trait on the player and in their mutation list.

Definition at line 125 of file mutation.cpp.

126{
127 // Take copy of argument because it might be a reference into a container
128 // we're about to erase from.
129 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
130 const trait_id trait = trait_;
131 const auto titer = my_traits.find( trait );
132 const auto miter = my_mutations.find( trait );
133 // These shouldn't be inlined, otherwise the sync check uses invalid iterators
134 bool no_trait = titer == my_traits.end();
135 bool no_mutation = miter == my_mutations.end();
136 if( no_trait ) {
137 my_traits.insert( trait );
138 } else {
139 my_traits.erase( titer );
140 }
141 if( no_trait != no_mutation ) {
142 debugmsg( "my_traits and my_mutations were out of sync for %s\n", trait.str() );
143 return;
144 }
145 if( no_mutation ) {
146 set_mutation( trait );
147 } else {
148 unset_mutation( trait );
149 }
150}

References debugmsg, my_mutations, my_traits, set_mutation(), string_id< T >::str(), and unset_mutation().

Referenced by newcharacter::add_traits(), clear_mutations(), avatar::create(), tutorial_game::init(), wish_mutate_callback::key(), avatar::randomize(), npc::randomize(), reset_scenario(), set_profession(), set_traits(), and gun_actor::shoot().

◆ unarmed_attack()

bool Character::unarmed_attack ( ) const

True if unarmed or wielding a weapon with the UNARMED_WEAPON flag.

Definition at line 211 of file melee.cpp.

212{
213 const item &weap = used_weapon();
214 return weap.is_null() || weap.has_flag( "UNARMED_WEAPON" );
215}

References item::has_flag(), item::is_null(), and used_weapon().

Referenced by mattack::copbot(), has_weapon(), conditional_t< T >::set_can_stow_weapon(), and conditional_t< T >::set_has_weapon().

◆ uncanny_dodge()

bool Character::uncanny_dodge ( )
overridevirtual

Handles the uncanny dodge bionic and effects, returns true if the creature successfully dodges.

Reimplemented from Creature.

Definition at line 10661 of file character.cpp.

10662{
10663 return character_funcs::try_uncanny_dodge( *this );
10664}
bool try_uncanny_dodge(Character &who)
Try to execute an uncanny dodge bionic ability.

References character_funcs::try_uncanny_dodge().

Referenced by mattack::grab(), and mattack::science().

◆ unimpaired_range()

int Character::unimpaired_range ( ) const

Returns the player maximum vision range factoring in mutations, diseases, and other effects.

Definition at line 630 of file character.cpp.

631{
632 return std::min( sight_max, 60 );
633}

References sight_max.

Referenced by sees().

◆ uninstall_bionic() [1/2]

bool Character::uninstall_bionic ( const bionic target_cbm,
monster installer,
player patient,
float  adjusted_skill 
)

Used by monster to perform surgery.

Definition at line 2136 of file bionics.cpp.

2138{
2139 if( installer.ammo[itype_anesthetic] <= 0 ) {
2140 if( g->u.sees( installer ) ) {
2141 add_msg( _( "The %s's anesthesia kit looks empty." ), installer.name() );
2142 }
2143 return false;
2144 }
2145
2146 const itype_id itemtype = target_cbm.info().itype();
2147 int difficulty = itemtype.is_valid() ? itemtype->bionic->difficulty : BIONIC_NOITEM_DIFFICULTY;
2148 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2149 int success = chance_of_success - rng( 1, 100 );
2150
2151 const time_duration duration = difficulty * 20_minutes;
2152 // don't stack up the effect
2153 if( !installer.has_effect( effect_operating ) ) {
2154 installer.add_effect( effect_operating, duration + 5_turns );
2155 }
2156
2157 if( patient.is_player() ) {
2158 add_msg( m_bad,
2159 _( "You feel a tiny pricking sensation in your right arm, and lose all sensation before abruptly blacking out." ) );
2160 } else if( g->u.sees( installer ) ) {
2161 add_msg( m_bad,
2162 _( "The %1$s gently inserts a syringe into %2$s's arm and starts injecting something while holding them down." ),
2163 installer.name(), patient.disp_name() );
2164 }
2165
2166 installer.ammo[itype_anesthetic] -= 1;
2167
2168 patient.add_effect( effect_narcosis, duration );
2169 patient.add_effect( effect_sleep, duration );
2170
2171 if( patient.is_player() ) {
2172 add_msg( _( "You fall asleep and %1$s starts operating." ), installer.disp_name() );
2173 } else if( g->u.sees( patient ) ) {
2174 add_msg( _( "%1$s falls asleep and %2$s starts operating." ), patient.disp_name(),
2175 installer.disp_name() );
2176 }
2177
2178 if( success > 0 ) {
2179
2180 if( patient.is_player() ) {
2181 add_msg( m_neutral, _( "Your parts are jiggled back into their familiar places." ) );
2182 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2183 } else if( patient.is_npc() && g->u.sees( patient ) ) {
2184 add_msg( m_neutral, _( "%s's parts are jiggled back into their familiar places." ),
2185 patient.disp_name() );
2186 add_msg( m_mixed, _( "Successfully removed %s." ), target_cbm.info().name );
2187 }
2188
2189 // remove power bank provided by bionic
2190 patient.mod_max_power_level( -target_cbm.info().capacity );
2191 patient.remove_bionic( target_cbm.id );
2192 const itype_id iid = itemtype.is_valid() &&
2193 !target_cbm.info().has_flag( flag_BIONIC_FAULTY ) ? itemtype : itype_burnt_out_bionic;
2195 if( itemtype.is_valid() ) {
2196 cbm.faults.emplace( fault_bionic_nonsterile );
2197 }
2198 get_map().add_item( patient.pos(), cbm );
2199 } else {
2200 bionics_uninstall_failure( installer, patient, difficulty, success, adjusted_skill );
2201 }
2202
2203 return false;
2204}
static const efftype_id effect_sleep("sleep")
static const efftype_id effect_operating("operating")
static const itype_id itype_anesthetic("anesthetic")
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4455
std::map< itype_id, int > ammo
Definition: monster.h:512
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:533
bool is_npc() const override
Definition: player.h:103

References _, Creature::add_effect(), monster::add_effect(), map::add_item(), add_msg(), monster::ammo, itype::bionic, bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_uninstall_failure(), bionic_data::capacity, disp_name(), monster::disp_name(), effect_narcosis, effect_operating, effect_sleep, fault_bionic_nonsterile, item::faults, flag_BIONIC_FAULTY, g, get_map(), Creature::has_effect(), bionic_data::has_flag(), bionic::id, bionic::info(), player::is_npc(), player::is_player(), string_id< T >::is_valid(), bionic_data::itype(), itype_anesthetic, itype_burnt_out_bionic, m_bad, m_mixed, m_neutral, mod_max_power_level(), bionic_data::name, monster::name(), pos(), remove_bionic(), rng(), calendar::start_of_cataclysm, and behavior::success.

◆ uninstall_bionic() [2/2]

bool Character::uninstall_bionic ( const bionic_id b_id,
player installer,
bool  autodoc = false,
int  skill_level = -1 
)

Initialize all the values needed to start the operation player_activity.

Definition at line 2032 of file bionics.cpp.

2034{
2035 // If malfunctioning bionics doesn't have associated item it gets predefined difficulty
2036 int difficulty = BIONIC_NOITEM_DIFFICULTY;
2037 if( b_id->itype().is_valid() ) {
2038 const itype *type = &*b_id->itype();
2039 if( type->bionic ) {
2040 difficulty = type->bionic->difficulty;
2041 }
2042 }
2043
2044 // removal of bionics adds +2 difficulty over installation
2045 float adjusted_skill;
2046 int pl_skill;
2047 if( autodoc ) {
2048 adjusted_skill = installer.bionics_adjusted_skill( skill_firstaid,
2051 skill_level );
2052 pl_skill = installer.bionics_pl_skill( skill_firstaid,
2055 skill_level );
2056 } else {
2057 adjusted_skill = installer.bionics_adjusted_skill( skill_electronics,
2060 skill_level );
2061 pl_skill = installer.bionics_pl_skill( skill_electronics,
2064 skill_level );
2065 }
2066
2067 int chance_of_success = bionic_manip_cos( adjusted_skill, difficulty + 2 );
2068
2069 // Surgery is imminent, retract claws or blade if active
2070 for( bionic &bio : *installer.my_bionics ) {
2071 if( bio.powered && bio.info().has_flag( flag_BIONIC_WEAPON ) ) {
2072 installer.deactivate_bionic( bio );
2073 }
2074 }
2075
2076 int success = chance_of_success - rng( 1, 100 );
2077 if( installer.has_trait( trait_DEBUG_BIONICS ) ) {
2078 perform_uninstall( b_id, difficulty, success, b_id->capacity, pl_skill );
2079 return true;
2080 }
2081 assign_activity( ACT_OPERATION, to_moves<int>( difficulty * 20_minutes ) );
2082
2083 activity.values.push_back( difficulty );
2084 activity.values.push_back( success );
2085 activity.values.push_back( units::to_kilojoule( b_id->capacity ) );
2086 activity.values.push_back( pl_skill );
2087 activity.str_values.push_back( "uninstall" );
2088 activity.str_values.push_back( b_id.str() );
2089 activity.str_values.push_back( "" ); // installer_name is unused for uninstall
2090 if( autodoc ) {
2091 activity.str_values.push_back( "true" );
2092 } else {
2093 activity.str_values.push_back( "false" );
2094 }
2095 for( const std::pair<const bodypart_str_id, int> &elem : b_id->occupied_bodyparts ) {
2096 add_effect( effect_under_op, difficulty * 20_minutes, elem.first->token, difficulty );
2097 }
2098
2099 return true;
2100}
void perform_uninstall(bionic_id bid, int difficulty, int success, const units::energy &power_lvl, int pl_skill)
Succes or failure of removal happens here.
Definition: bionics.cpp:2102

References ACT_OPERATION, activity, Creature::add_effect(), assign_activity(), iexamine::autodoc(), bionic_manip_cos(), BIONIC_NOITEM_DIFFICULTY, bionics_adjusted_skill(), bionics_pl_skill(), bionic_data::capacity, deactivate_bionic(), effect_under_op, flag_BIONIC_WEAPON, bionic_data::has_flag(), has_trait(), bionic::info(), string_id< T >::is_valid(), bionic_data::itype(), my_bionics, bionic_data::occupied_bodyparts, perform_uninstall(), bionic::powered, rng(), skill_computer, skill_electronics, skill_firstaid, skill_mechanics, string_id< T >::str(), player_activity::str_values, behavior::success, units::to_kilojoule(), trait_DEBUG_BIONICS, type, and player_activity::values.

Referenced by iexamine::autodoc().

◆ unset_mutation()

void Character::unset_mutation ( const trait_id trait_)

Definition at line 165 of file mutation.cpp.

166{
167 // Take copy of argument because it might be a reference into a container
168 // we're about to erase from.
169 // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
170 const trait_id trait = trait_;
171 const auto iter = my_mutations.find( trait );
172 if( iter == my_mutations.end() ) {
173 return;
174 }
175 my_mutations.erase( iter );
177 mutation_loss_effect( trait );
180}

References mutation_loss_effect(), my_mutations, rebuild_mutation_cache(), recalc_sight_limits(), and reset_encumbrance().

Referenced by clear_mutations(), wish_mutate_callback::key(), marloss_common(), mutate_towards(), iuse::mycus(), remove_mutation(), talk_effect_fun_t::set_remove_trait(), switch_mutations(), test_crossing_threshold(), toggle_trait(), and try_reject_mutagen().

◆ unwield()

bool Character::unwield ( )

Removes currently wielded item (if any)

Definition at line 3135 of file character.cpp.

3136{
3137 item &weapon = primary_weapon();
3138 if( weapon.is_null() ) {
3139 return true;
3140 }
3141
3142 if( !can_unwield( weapon ).success() ) {
3143 return false;
3144 }
3145
3146 const std::string query = string_format( _( "Stop wielding %s?" ), weapon.tname() );
3147
3148 if( !dispose_item( item_location( *this, &weapon ), query ) ) {
3149 return false;
3150 }
3151
3152 inv.unsort();
3153
3154 return true;
3155}

References _, can_unwield(), dispose_item(), inv, item::is_null(), primary_weapon(), string_format(), behavior::success, item::tname(), and inventory::unsort().

Referenced by character_funcs::try_wield_contents(), avatar::wield(), and avatar_action::wield().

◆ update_body() [1/2]

void Character::update_body ( )

Updates all "biology" by one turn.

Should be called once every turn.

Definition at line 4703 of file character.cpp.

4704{
4706}
void update_body()
Updates all "biology" by one turn.
Definition: character.cpp:4703

References calendar::turn, and update_body().

Referenced by game::do_turn(), npc::npc_update_body(), npc::on_load(), and update_body().

◆ update_body() [2/2]

void Character::update_body ( const time_point from,
const time_point to 
)

Updates all "biology" as if time between from and to passed.

Definition at line 4708 of file character.cpp.

4709{
4710 if( !is_npc() ) {
4711 update_stamina( to_turns<int>( to - from ) );
4712 }
4713 update_stomach( from, to );
4715 if( ticks_between( from, to, 3_minutes ) > 0 ) {
4716 magic->update_mana( *this->as_player(), to_turns<double>( 3_minutes ) );
4717 }
4718 const int five_mins = ticks_between( from, to, 5_minutes );
4719 if( five_mins > 0 ) {
4721 update_needs( five_mins );
4722 regen( five_mins );
4723 }
4724 if( ticks_between( from, to, 24_hours ) > 0 ) {
4726 }
4727
4728 const int thirty_mins = ticks_between( from, to, 30_minutes );
4729 if( thirty_mins > 0 ) {
4730 // Radiation kills health even at low doses
4732 }
4733
4734 for( const auto &v : vitamin::all() ) {
4735 const time_duration rate = vitamin_rate( v.first );
4736 if( rate > 0_turns ) {
4737 int qty = ticks_between( from, to, rate );
4738 if( qty > 0 ) {
4739 vitamin_mod( v.first, 0 - qty );
4740 }
4741
4742 } else if( rate < 0_turns ) {
4743 // mutations can result in vitamins being generated (but never accumulated)
4744 int qty = ticks_between( from, to, -rate );
4745 if( qty > 0 ) {
4746 vitamin_mod( v.first, qty );
4747 }
4748 }
4749 }
4750
4751 do_skill_rust();
4752}
int ticks_between(const time_point &from, const time_point &to, const time_duration &tick_length)
Definition: character.cpp:4696
static const trait_id trait_RADIOGENIC("RADIOGENIC")
void check_needs_extremes()
Kills the player if too hungry, stimmed up etc., forces tired player to sleep and prints warnings.
Definition: character.cpp:5007
void do_skill_rust()
Definition: character.cpp:3600
void update_needs(int rate_multiplier)
Increases hunger, thirst, fatigue and stimulants wearing off.
Definition: character.cpp:4811
virtual void update_health(int external_modifiers=0)
Handles health fluctuations over time.
Definition: character.cpp:4659
void regen(int rate_multiplier)
Handles passive regeneration of pain and maybe hp.
Definition: character.cpp:4573
void update_stomach(const time_point &from, const time_point &to)
Updates the stomach to give accurate hunger messages.
Definition: character.cpp:4768
time_duration vitamin_rate(const vitamin_id &vit) const
Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.
void enforce_minimum_healing()
Definition: character.cpp:4649
void update_stamina(int turns)
Regenerates stamina.
Definition: character.cpp:7173

References vitamin::all(), Creature::as_player(), check_needs_extremes(), do_skill_rust(), enforce_minimum_healing(), get_rad(), has_trait(), Creature::is_npc(), magic, recalculate_enchantment_cache(), regen(), ticks_between(), trait_RADIOGENIC, update_health(), update_needs(), update_stamina(), update_stomach(), vitamin_mod(), and vitamin_rate().

◆ update_bodytemp()

void Character::update_bodytemp ( const map m,
const weather_manager weather 
)

Maintains body temperature.

Calculations that affect all body parts equally go here, not in the loop

Source : http://www.atc.army.mil/weather/windchill.pdf

Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.

1200 turns in low risk, + 3 tics 450 turns in moderate risk, + 8 tics 50 turns in high risk, +72 tics

Let's say frostnip @ 1800 tics, frostbite @ 3600 tics

Chunked into 8 parts (http://imgur.com/xlTPmJF)

– 2 hour risk – Between 30F and 10F Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph – 45 minute risk – Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph Between 10F and -5F, greater than 20mph Less than -5F, less than 10 mph Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph – 5 minute risk – Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph Less than -35F, more than 10 mp

Definition at line 5226 of file character.cpp.

5227{
5228 if( has_trait( trait_DEBUG_NOTEMP ) ) {
5229 temp_cur.fill( BODYTEMP_NORM );
5230 temp_conv.fill( BODYTEMP_NORM );
5231 return;
5232 }
5233 /* Cache calls to g->get_temperature( player position ), used in several places in function */
5234 const auto player_local_temp = weather.get_temperature( pos() );
5235 // NOTE : visit weather.h for some details on the numbers used
5236 // In Celsius / 100
5237 int Ctemperature = static_cast<int>( 100 * units::fahrenheit_to_celsius( player_local_temp ) );
5238 const w_point &weather_point = get_weather().get_precise();
5239 int vehwindspeed = 0;
5240 const optional_vpart_position vp = m.veh_at( pos() );
5241 if( vp ) {
5242 vehwindspeed = std::abs( vp->vehicle().velocity / 100 ); // vehicle velocity in mph
5243 }
5244 const oter_id &cur_om_ter = overmap_buffer.ter( global_omt_location() );
5245 bool sheltered = weather::is_sheltered( m, pos() );
5246 double total_windpower = get_local_windpower( weather.windspeed + vehwindspeed, cur_om_ter,
5247 pos(),
5248 weather.winddirection, sheltered );
5249 int air_humidity = get_local_humidity( weather_point.humidity, weather.weather_id,
5250 sheltered );
5251 // Let's cache this not to check it num_bp times
5252 const bool has_bark = has_trait( trait_BARK );
5253 const bool has_heatsink = has_bionic( bio_heatsink ) || is_wearing( itype_rm13_armor_on ) ||
5255 const bool has_climate_control = in_climate_control();
5256 const bool use_floor_warmth = can_use_floor_warmth();
5257 // In bodytemp units
5258 const int ambient_norm = 1900 - BODYTEMP_NORM;
5259
5260 /**
5261 * Calculations that affect all body parts equally go here, not in the loop
5262 */
5263 const int sunlight_warmth = weather::is_in_sunlight( m, pos(), weather.weather_id )
5264 ? ( weather.weather_id->sun_intensity == sun_intensity_type::high ? 1000 : 500 )
5265 : 0;
5266 const int best_fire = get_heat_radiation( pos(), true );
5267 const bool pyromania = has_trait( trait_PYROMANIA );
5268
5269 const int lying_warmth = use_floor_warmth ? floor_warmth( pos() ) : 0;
5270 const int water_temperature_raw =
5271 100 * units::fahrenheit_to_celsius( weather.get_water_temperature( pos() ) );
5272 // Rescale so that 0C is 0 (FREEZING) and 30C is 5k (NORM).
5273 const int water_temperature = water_temperature_raw * 5 / 3;
5274
5275 // Correction of body temperature due to traits and mutations
5276 // Lower heat is applied always
5277 const int mutation_heat_low = bodytemp_modifier_traits( true );
5278 const int mutation_heat_high = bodytemp_modifier_traits( false );
5279 // Difference between high and low is the "safe" heat - one we only apply if it's beneficial
5280 const int mutation_heat_bonus = mutation_heat_high - mutation_heat_low;
5281
5282 // Note: this is included in @ref weather::get_temperature(), so don't add to bodytemp!
5283 const int h_radiation = get_heat_radiation( pos(), false );
5284
5285 // If you're standing in water, air temperature is replaced by water temperature. No wind.
5286 const ter_id ter_at_pos = m.ter( pos() );
5287 const bool submerged = !in_vehicle && ter_at_pos->has_flag( TFLAG_DEEP_WATER );
5288 const bool submerged_low = !in_vehicle && ( submerged || ter_at_pos->has_flag( TFLAG_SWIMMABLE ) );
5289
5290 std::map<bodypart_id, std::vector<const item *>> clothing_map;
5291 std::map<bodypart_id, std::vector<const item *>> bonus_clothing_map;
5292 for( const bodypart_id &bp : get_all_body_parts() ) {
5293 clothing_map.emplace( bp, std::vector<const item *>() );
5294 bonus_clothing_map.emplace( bp, std::vector<const item *>() );
5295 // HACK: we're using temp_conv here to temporarily save
5296 // temperature values from before equalization.
5297 temp_conv[bp->token] = temp_cur[bp->token];
5298 }
5299
5300 // EQUALIZATION
5301 // We run it outside the loop because we can and so we should
5302 // Also, it makes bonus heat application more stable
5303 // TODO: Affect future convection temperature instead (might require adding back to loop)
5309
5312
5315
5316 for( const item &it : worn ) {
5317 // TODO: Port body part set id changes
5318 const body_part_set &covered = it.get_covered_body_parts();
5319 for( size_t i = 0; i < num_bp; i++ ) {
5320 body_part token = static_cast<body_part>( i );
5321 if( covered.test( token ) ) {
5322 clothing_map[convert_bp( token )].emplace_back( &it );
5323 }
5324 if( it.has_flag( flag_HOOD ) ) {
5325 bonus_clothing_map[body_part_head].emplace_back( &it );
5326 }
5327 if( it.has_flag( flag_COLLAR ) ) {
5328 bonus_clothing_map[body_part_mouth].emplace_back( &it );
5329 }
5330 if( it.has_flag( flag_POCKETS ) ) {
5331 bonus_clothing_map[body_part_hand_l].emplace_back( &it );
5332 bonus_clothing_map[body_part_hand_r].emplace_back( &it );
5333 }
5334 }
5335 }
5336 // If player is wielding something large, pockets are not usable
5337 const item &weapon = primary_weapon();
5338 if( weapon.volume() >= 500_ml ) {
5339 bonus_clothing_map[body_part_hand_l].clear();
5340 bonus_clothing_map[body_part_hand_r].clear();
5341 }
5342 // If player's head is encumbered, hood can't be put up
5343 if( encumb( body_part_head->token ) >= 10 ) {
5344 bonus_clothing_map[body_part_head].clear();
5345 }
5346 // Similar for mouth
5347 if( encumb( body_part_mouth->token ) >= 10 ) {
5348 bonus_clothing_map[body_part_mouth].clear();
5349 }
5350
5351 std::map<bodypart_id, int> warmth_per_bp = warmth::from_clothing( clothing_map );
5352 std::map<bodypart_id, int> bonus_warmth_per_bp = warmth::bonus_from_clothing( bonus_clothing_map );
5353 for( const auto &pr : warmth::from_effects( *this ) ) {
5354 warmth_per_bp[pr.first] += pr.second;
5355 }
5356
5357 std::map<bodypart_id, int> wind_res_per_bp = warmth::wind_resistance_from_clothing( clothing_map );
5358 std::map<bodypart_id, int> wind_res_per_bp_bonus = warmth::wind_resistance_from_clothing(
5359 bonus_clothing_map );
5360 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5361 int exposed = std::max( 0, 100 - bp_wind_res.second );
5362 int exposed_bonus = std::max( 0, 100 - wind_res_per_bp_bonus.at( bp_wind_res.first ) );
5363 int exposed_final = exposed * exposed_bonus / ( 100 * 100 );
5364 bp_wind_res.second = 100 - exposed_final;
5365 }
5367 for( std::pair<const bodypart_id, int> &bp_wind_res : wind_res_per_bp ) {
5368 bp_wind_res.second = 100;
5369 }
5370 }
5371 // We might not use this at all, so leave it empty
5372 // If we do need to use it, we'll initialize it (once) there
5373 std::map<bodypart_id, int> fire_armor_per_bp;
5374
5375 // Current temperature and converging temperature calculations
5376 for( const bodypart_id &bp : get_all_body_parts() ) {
5377 // Skip eyes
5378 if( bp == bodypart_id( "eyes" ) ) {
5379 continue;
5380 }
5381
5382 const bool submerged_bp = submerged ||
5383 ( submerged_low &&
5384 ( bp == body_part_foot_l ||
5385 bp == body_part_foot_r ||
5386 bp == body_part_leg_l ||
5387 bp == body_part_leg_r ) );
5388 // This adjusts the temperature scale to match the bodytemp scale
5389 const int adjusted_temp = submerged_bp ?
5390 water_temperature :
5391 ( Ctemperature - ambient_norm );
5392
5393 // Represents the fact that the body generates heat when it is cold.
5394 double scaled_temperature = logarithmic_range( BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT,
5395 temp_cur[bp->token] );
5396 // Produces a smooth curve between 30.0 and 60.0.
5397 double homeostasis_adjustment = 30.0 * ( 1.0 + scaled_temperature );
5398 int clothing_warmth_adjustment = static_cast<int>( homeostasis_adjustment * warmth_per_bp[bp] );
5399 int clothing_warmth_adjusted_bonus = static_cast<int>( homeostasis_adjustment *
5400 bonus_warmth_per_bp[bp] );
5401 // WINDCHILL
5402 double bp_windpower = total_windpower * ( 1 - wind_res_per_bp[bp] / 100.0 );
5403 // Calculate windchill
5404 int windchill = submerged_bp
5405 ? 0
5406 : get_local_windchill( player_local_temp,
5407 air_humidity,
5408 bp_windpower );
5409
5410 // Convergent temperature is affected by ambient temperature,
5411 // clothing warmth, and body wetness.
5412 int bp_conv = adjusted_temp
5413 + windchill * 100
5414 + clothing_warmth_adjustment
5415 + mutation_heat_low
5416 + sunlight_warmth;
5417
5418 // Bark : lowers blister count to -5; harder to get blisters
5419 // If the counter is high, your skin starts to burn
5420 int blister_count = ( has_bark ? -5 : 0 );
5421
5422 if( frostbite_timer[bp->token] > 0 ) {
5423 frostbite_timer[bp->token] -= std::min( 5, h_radiation );
5424 }
5425 blister_count += h_radiation - 111 > 0 ?
5426 std::max( static_cast<int>( std::sqrt( h_radiation - 111 ) ), 0 ) : 0;
5427
5428 if( has_heatsink ) {
5429 blister_count -= 20;
5430 }
5431 if( fire_armor_per_bp.empty() && blister_count > 0 ) {
5432 fire_armor_per_bp = get_armor_fire( clothing_map );
5433 }
5434 // BLISTERS : Skin gets blisters from intense heat exposure.
5435 // Fire protection protects from blisters.
5436 // Heatsinks give near-immunity.
5437 if( blister_count - fire_armor_per_bp[bp] > 0 ) {
5438 add_effect( effect_blisters, 1_turns, bp->token );
5439 if( pyromania ) {
5440 add_morale( MORALE_PYROMANIA_NEARFIRE, 10, 10, 1_hours,
5441 30_minutes ); // Proximity that's close enough to harm us gives us a bit of a thrill
5443 }
5444 } else if( pyromania && best_fire >= 1 ) { // Only give us fire bonus if there's actually fire
5445 add_morale( MORALE_PYROMANIA_NEARFIRE, 5, 5, 30_minutes,
5446 15_minutes ); // Gain a much smaller mood boost even if it doesn't hurt us
5448 }
5449
5450 // Climate Control eases the effects of high and low ambient temps
5451 if( has_climate_control ) {
5452 bp_conv = temp_corrected_by_climate_control( bp_conv );
5453 }
5454
5455 int bonus_fire_warmth = best_fire * 500;
5456
5457 const int comfortable_warmth = bonus_fire_warmth + lying_warmth;
5458 const int bonus_warmth = comfortable_warmth + mutation_heat_bonus + clothing_warmth_adjusted_bonus;
5459 if( bonus_warmth > 0 ) {
5460 // Approximate bp_conv needed to reach comfortable temperature in this very turn
5461 // Basically inverted formula for temp_cur below
5462 int desired = 501 * BODYTEMP_NORM - 499 * temp_cur[bp->token];
5463 if( std::abs( BODYTEMP_NORM - desired ) < 1000 ) {
5464 desired = BODYTEMP_NORM; // Ensure that it converges
5465 } else if( desired > BODYTEMP_HOT ) {
5466 desired = BODYTEMP_HOT; // Cap excess at sane temperature
5467 }
5468
5469 if( desired < bp_conv ) {
5470 // Too hot, can't help here
5471 } else if( desired < bp_conv + bonus_warmth ) {
5472 // Use some heat, but not all of it
5473 bp_conv = desired;
5474 } else {
5475 // Use all the heat
5476 bp_conv += bonus_warmth;
5477 }
5478
5479 // Morale bonus for comfiness - only if actually comfy (not too warm/cold)
5480 // Spread the morale bonus in time.
5481 if( comfortable_warmth > 0 &&
5482 // TODO: make this simpler and use time_duration/time_point
5483 to_turn<int>( calendar::turn ) % to_turns<int>( 1_minutes ) == to_turns<int>
5484 ( 1_minutes * bp->token ) / to_turns<int>( 1_minutes * num_bp ) &&
5486 get_effect_int( effect_hot, num_bp ) == 0 &&
5487 temp_cur[bp->token] > BODYTEMP_COLD && temp_cur[bp->token] <= BODYTEMP_NORM ) {
5488 add_morale( MORALE_COMFY, 1, 10, 2_minutes, 1_minutes, true );
5489 }
5490 }
5491
5492 // The current temperature model can't account for water temperature conduction well
5493 // Hack: cut non-water effects by 80% when in water
5494 if( submerged_bp ) {
5495 bp_conv = ( ( bp_conv - adjusted_temp ) / 5 ) + adjusted_temp;
5496 }
5497
5498 // FINAL CALCULATION : Increments current body temperature towards convergent.
5499 int temp_before = temp_cur[bp->token];
5500 int temp_difference = temp_before - bp_conv; // Negative if the player is warming up.
5501 int rounding_error = 0;
5502 // If temp_diff is small, the player cannot warm up due to rounding errors. This fixes that.
5503 if( temp_difference < 0 && temp_difference > -600 ) {
5504 rounding_error = 1;
5505 }
5506 // exp(-0.001) : half life of 60 minutes, exp(-0.002) : half life of 30 minutes,
5507 // exp(-0.003) : half life of 20 minutes, exp(-0.004) : half life of 15 minutes
5508 static const double change_mult_air = std::exp( -0.002 );
5509 static const double change_mult_water = std::exp( -0.008 );
5510 const double change_mult = submerged_bp ? change_mult_water : change_mult_air;
5511 if( temp_cur[bp->token] != bp_conv ) {
5512 temp_cur[bp->token] = static_cast<int>( temp_difference * change_mult )
5513 + bp_conv + rounding_error;
5514 }
5515 int temp_after = temp_cur[bp->token];
5516 // PENALTIES
5517 if( temp_cur[bp->token] < BODYTEMP_FREEZING ) {
5518 add_effect( effect_cold, 1_turns, bp->token, 3 );
5519 } else if( temp_cur[bp->token] < BODYTEMP_VERY_COLD ) {
5520 add_effect( effect_cold, 1_turns, bp->token, 2 );
5521 } else if( temp_cur[bp->token] < BODYTEMP_COLD ) {
5522 add_effect( effect_cold, 1_turns, bp->token, 1 );
5523 } else if( temp_cur[bp->token] > BODYTEMP_SCORCHING ) {
5524 add_effect( effect_hot, 1_turns, bp->token, 3 );
5525 if( bp->main_part.id() == bp ) {
5526 add_effect( effect_hot_speed, 1_turns, bp->token, 3 );
5527 }
5528 } else if( temp_cur[bp->token] > BODYTEMP_VERY_HOT ) {
5529 add_effect( effect_hot, 1_turns, bp->token, 2 );
5530 if( bp->main_part.id() == bp ) {
5531 add_effect( effect_hot_speed, 1_turns, bp->token, 2 );
5532 }
5533 } else if( temp_cur[bp->token] > BODYTEMP_HOT ) {
5534 add_effect( effect_hot, 1_turns, bp->token, 1 );
5535 if( bp->main_part.id() == bp ) {
5536 add_effect( effect_hot_speed, 1_turns, bp->token, 1 );
5537 }
5538 } else {
5539 if( temp_cur[bp->token] >= BODYTEMP_COLD ) {
5540 remove_effect( effect_cold, bp->token );
5541 }
5542 if( temp_cur[bp->token] <= BODYTEMP_HOT ) {
5543 remove_effect( effect_hot, bp->token );
5544 remove_effect( effect_hot_speed, bp->token );
5545 }
5546 }
5547
5548 // FROSTBITE - only occurs to hands, feet, face
5549 /**
5550
5551 Source : http://www.atc.army.mil/weather/windchill.pdf
5552
5553 Temperature and wind chill are main factors, mitigated by clothing warmth. Each 10 warmth protects against 2C of cold.
5554
5555 1200 turns in low risk, + 3 tics
5556 450 turns in moderate risk, + 8 tics
5557 50 turns in high risk, +72 tics
5558
5559 Let's say frostnip @ 1800 tics, frostbite @ 3600 tics
5560
5561 >> Chunked into 8 parts (http://imgur.com/xlTPmJF)
5562 -- 2 hour risk --
5563 Between 30F and 10F
5564 Between 10F and -5F, less than 20mph, -4x + 3y - 20 > 0, x : F, y : mph
5565 -- 45 minute risk --
5566 Between 10F and -5F, less than 20mph, -4x + 3y - 20 < 0, x : F, y : mph
5567 Between 10F and -5F, greater than 20mph
5568 Less than -5F, less than 10 mph
5569 Less than -5F, more than 10 mph, -4x + 3y - 170 > 0, x : F, y : mph
5570 -- 5 minute risk --
5571 Less than -5F, more than 10 mph, -4x + 3y - 170 < 0, x : F, y : mph
5572 Less than -35F, more than 10 mp
5573 **/
5574
5575 if( bp == body_part_mouth || bp == body_part_foot_r ||
5576 bp == body_part_foot_l || bp == body_part_hand_r || bp == body_part_hand_l ) {
5577 // Handle the frostbite timer
5578 // Need temps in F, windPower already in mph
5579 int wetness_percentage = 100 * body_wetness[bp->token] / drench_capacity[bp->token]; // 0 - 100
5580 // Warmth gives a slight buff to temperature resistance
5581 // Wetness gives a heavy nerf to temperature resistance
5582 double adjusted_warmth = warmth_per_bp.at( bp ) - wetness_percentage;
5583 int Ftemperature = static_cast<int>( player_local_temp + 0.2 * adjusted_warmth );
5584 // Windchill reduced by your armor
5585 int FBwindPower = static_cast<int>(
5586 total_windpower * ( 1 - wind_res_per_bp[ bp ] / 100.0 ) );
5587
5588 int intense = get_effect_int( effect_frostbite, bp->token );
5589
5590 // This has been broken down into 8 zones
5591 // Low risk zones (stops at frostnip)
5592 if( temp_cur[bp->token] < BODYTEMP_COLD &&
5593 ( ( Ftemperature < 30 && Ftemperature >= 10 ) ||
5594 ( Ftemperature < 10 && Ftemperature >= -5 &&
5595 FBwindPower < 20 && -4 * Ftemperature + 3 * FBwindPower - 20 >= 0 ) ) ) {
5596 if( frostbite_timer[bp->token] < 2000 ) {
5597 frostbite_timer[bp->token] += 3;
5598 }
5599 if( one_in( 100 ) && !has_effect( effect_frostbite, bp->token ) ) {
5600 add_msg( m_warning, _( "Your %s will be frostnipped in the next few hours." ),
5601 body_part_name( bp->token ) );
5602 }
5603 // Medium risk zones
5604 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5605 ( ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower < 20 &&
5606 -4 * Ftemperature + 3 * FBwindPower - 20 < 0 ) ||
5607 ( Ftemperature < 10 && Ftemperature >= -5 && FBwindPower >= 20 ) ||
5608 ( Ftemperature < -5 && FBwindPower < 10 ) ||
5609 ( Ftemperature < -5 && FBwindPower >= 10 &&
5610 -4 * Ftemperature + 3 * FBwindPower - 170 >= 0 ) ) ) {
5611 frostbite_timer[bp->token] += 8;
5612 if( one_in( 100 ) && intense < 2 ) {
5613 add_msg( m_warning, _( "Your %s will be frostbitten within the hour!" ),
5614 body_part_name( bp->token ) );
5615 }
5616 // High risk zones
5617 } else if( temp_cur[bp->token] < BODYTEMP_COLD &&
5618 ( ( Ftemperature < -5 && FBwindPower >= 10 &&
5619 -4 * Ftemperature + 3 * FBwindPower - 170 < 0 ) ||
5620 ( Ftemperature < -35 && FBwindPower >= 10 ) ) ) {
5621 frostbite_timer[bp->token] += 72;
5622 if( one_in( 100 ) && intense < 2 ) {
5623 add_msg( m_warning, _( "Your %s will be frostbitten any minute now!" ),
5624 body_part_name( bp->token ) );
5625 }
5626 // Risk free, so reduce frostbite timer
5627 } else {
5628 frostbite_timer[bp->token] -= 3;
5629 }
5630
5631 // Handle the bestowing of frostbite
5632 if( frostbite_timer[bp->token] < 0 ) {
5633 frostbite_timer[bp->token] = 0;
5634 } else if( frostbite_timer[bp->token] > 4200 ) {
5635 // This ensures that the player will recover in at most 3 hours.
5636 frostbite_timer[bp->token] = 4200;
5637 }
5638 // Frostbite, no recovery possible
5639 if( frostbite_timer[bp->token] >= 3600 ) {
5640 add_effect( effect_frostbite, 1_turns, bp->token, 2 );
5642 // Else frostnip, add recovery if we were frostbitten
5643 } else if( frostbite_timer[bp->token] >= 1800 ) {
5644 if( intense == 2 ) {
5645 add_effect( effect_frostbite_recovery, 1_turns, bp->token );
5646 }
5647 add_effect( effect_frostbite, 1_turns, bp->token, 1 );
5648 // Else fully recovered
5649 } else if( frostbite_timer[bp->token] == 0 ) {
5650 remove_effect( effect_frostbite, bp->token );
5652 }
5653 }
5654 // Warn the player if condition worsens
5655 // HACK: we want overall temperature change, including equalization, and temp_conv
5656 // at this moment contains temperature values from before the equalization.
5657 temp_before = temp_conv[bp->token];
5658 if( temp_before > BODYTEMP_FREEZING && temp_after <= BODYTEMP_FREEZING ) {
5659 //~ %s is bodypart
5660 add_msg( m_warning, _( "You feel your %s beginning to go numb from the cold!" ),
5661 body_part_name( bp->token ) );
5662 } else if( temp_before > BODYTEMP_VERY_COLD && temp_after <= BODYTEMP_VERY_COLD ) {
5663 //~ %s is bodypart
5664 add_msg( m_warning, _( "You feel your %s getting very cold." ),
5665 body_part_name( bp->token ) );
5666 } else if( temp_before > BODYTEMP_COLD && temp_after <= BODYTEMP_COLD ) {
5667 //~ %s is bodypart
5668 add_msg( m_warning, _( "You feel your %s getting chilly." ),
5669 body_part_name( bp->token ) );
5670 } else if( temp_before < BODYTEMP_SCORCHING && temp_after >= BODYTEMP_SCORCHING ) {
5671 //~ %s is bodypart
5672 add_msg( m_bad, _( "You feel your %s getting red hot from the heat!" ),
5673 body_part_name( bp->token ) );
5674 } else if( temp_before < BODYTEMP_VERY_HOT && temp_after >= BODYTEMP_VERY_HOT ) {
5675 //~ %s is bodypart
5676 add_msg( m_warning, _( "You feel your %s getting very hot." ),
5677 body_part_name( bp->token ) );
5678 } else if( temp_before < BODYTEMP_HOT && temp_after >= BODYTEMP_HOT ) {
5679 //~ %s is bodypart
5680 add_msg( m_warning, _( "You feel your %s getting warm." ),
5681 body_part_name( bp->token ) );
5682 }
5683
5684 // Note: Numbers are based off of BODYTEMP at the top of weather.h
5685 // If torso is BODYTEMP_COLD which is 34C, the early stages of hypothermia begin
5686 // constant shivering will prevent the player from falling asleep.
5687 // Otherwise, if any other body part is BODYTEMP_VERY_COLD, or 31C
5688 // AND you have frostbite, then that also prevents you from sleeping
5689 if( in_sleep_state() ) {
5690 int curr_temperature = temp_cur[bp->token];
5691 if( bp == body_part_torso && curr_temperature <= BODYTEMP_COLD ) {
5692 add_msg( m_warning, _( "Your shivering prevents you from sleeping." ) );
5693 wake_up();
5694 } else if( bp != body_part_torso && curr_temperature <= BODYTEMP_VERY_COLD &&
5696 add_msg( m_warning, _( "You are too cold. Your frostbite prevents you from sleeping." ) );
5697 wake_up();
5698 }
5699 }
5700
5701 // Warn the player that wind is going to be a problem.
5702 // But only if it can be a problem, no need to spam player with "wind chills your scorching body"
5703 if( bp_conv <= BODYTEMP_COLD && windchill < -10 && one_in( 200 ) ) {
5704 add_msg( m_bad, _( "The wind is making your %s feel quite cold." ),
5705 body_part_name( bp->token ) );
5706 } else if( bp_conv <= BODYTEMP_COLD && windchill < -20 && one_in( 100 ) ) {
5707 add_msg( m_bad,
5708 _( "The wind is very strong, you should find some more wind-resistant clothing for your %s." ),
5709 body_part_name( bp->token ) );
5710 } else if( bp_conv <= BODYTEMP_COLD && windchill < -30 && one_in( 50 ) ) {
5711 add_msg( m_bad, _( "Your clothing is not providing enough protection from the wind for your %s!" ),
5712 body_part_name( bp->token ) );
5713 }
5714
5715 // Set temp_conv just once per bp for readability
5716 // TODO: Remove temp_conv, it's only really for display, so should not be in Character
5717 temp_conv[bp->token] = bp_conv;
5718 }
5719}
const bodypart_str_id body_part_foot_r("foot_r")
const bodypart_str_id body_part_hand_r("hand_r")
const bodypart_str_id body_part_leg_l("leg_l")
const bodypart_str_id body_part_arm_l("arm_l")
const bodypart_str_id body_part_torso("torso")
const bodypart_str_id body_part_leg_r("leg_r")
const bodypart_str_id body_part_mouth("mouth")
const bodypart_str_id body_part_head("head")
const bodypart_str_id body_part_hand_l("hand_l")
const bodypart_str_id body_part_foot_l("foot_l")
static const efftype_id effect_cold("cold")
static const trait_id trait_DEBUG_NOTEMP("DEBUG_NOTEMP")
static const trait_id trait_BARK("BARK")
static const flag_str_id flag_POCKETS("POCKETS")
static const efftype_id effect_hot("hot")
static const flag_str_id flag_HOOD("HOOD")
static const trait_id trait_PYROMANIA("PYROMANIA")
static const efftype_id effect_blisters("blisters")
static const efftype_id effect_frostbite_recovery("frostbite_recovery")
static const efftype_id effect_hot_speed("hot_speed")
static const flag_str_id flag_COLLAR("COLLAR")
static const efftype_id effect_frostbite("frostbite")
int temp_corrected_by_climate_control(int temperature) const
Value of the body temperature corrected by climate control.
Definition: character.cpp:9569
std::map< bodypart_id, int > get_armor_fire(const std::map< bodypart_id, std::vector< const item * > > &clothing_map) const
Returns overall fire resistance.
Definition: character.cpp:8257
bool can_use_floor_warmth() const
Can the player lie down and cover self with blankets etc.
Definition: character.cpp:9447
int bodytemp_modifier_traits(bool overheated) const
Correction factor of the body temperature due to traits and mutations.
Definition: character.cpp:9551
bool in_climate_control()
Returns true if the player is in a climate controlled area or armor.
Definition: character.cpp:3853
void temp_equalizer(const bodypart_id &bp1, const bodypart_id &bp2)
Equalizes heat between body parts.
Definition: character.cpp:5721
int floor_warmth(const tripoint &pos) const
Final warmth from the floor.
Definition: character.cpp:9536
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1074
ter_id ter(const tripoint &p) const
Definition: map.cpp:1563
int get_heat_radiation(const tripoint &location, bool direct)
Definition: game.cpp:1800
const morale_type MORALE_COMFY("morale_comfy")
constexpr double fahrenheit_to_celsius(double fahrenheit)
std::map< bodypart_id, int > bonus_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9430
std::map< bodypart_id, int > wind_resistance_from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Returns wind resistance provided by armor, etc.
Definition: character.cpp:3909
std::map< bodypart_id, int > from_effects(const Character &c)
Definition: character.cpp:9436
std::map< bodypart_id, int > from_clothing(const std::map< bodypart_id, std::vector< const item * > > &clothing_map)
Definition: character.cpp:9424
bool is_in_sunlight(const map &m, const tripoint &p, const weather_type_id &weather)
Definition: weather.cpp:1171
bool is_sheltered(const map &m, const tripoint &p)
Definition: weather.cpp:1162
bool has_flag(const std::string &flag) const
Definition: mapdata.h:421

References _, Creature::add_effect(), add_morale(), add_msg(), bio_heatsink, body_part_arm_l, body_part_arm_r, body_part_foot_l, body_part_foot_r, body_part_hand_l, body_part_hand_r, body_part_head, body_part_leg_l, body_part_leg_r, body_part_mouth, body_part_name(), body_part_torso, body_wetness, BODYTEMP_COLD, BODYTEMP_FREEZING, BODYTEMP_HOT, bodytemp_modifier_traits(), BODYTEMP_NORM, BODYTEMP_SCORCHING, BODYTEMP_VERY_COLD, BODYTEMP_VERY_HOT, warmth::bonus_from_clothing(), can_use_floor_warmth(), convert_bp(), drench_capacity, effect_blisters, effect_cold, effect_frostbite, effect_frostbite_recovery, effect_hot, effect_hot_speed, encumb(), units::fahrenheit_to_celsius(), flag_COLLAR, flag_HOOD, flag_POCKETS, floor_warmth(), warmth::from_clothing(), warmth::from_effects(), frostbite_timer, Creature::get_all_body_parts(), get_armor_fire(), Creature::get_effect_int(), get_heat_radiation(), get_local_humidity(), get_local_windchill(), get_local_windpower(), weather_manager::get_precise(), get_weather(), global_omt_location(), has_active_mutation(), has_bionic(), Creature::has_effect(), map_data_common_t::has_flag(), has_trait(), high, w_point::humidity, in_climate_control(), in_sleep_state(), in_vehicle, weather::is_in_sunlight(), weather::is_sheltered(), is_wearing(), itype_rm13_armor_on, logarithmic_range(), m_bad, m_warning, MORALE_COMFY, MORALE_PYROMANIA_NEARFIRE, MORALE_PYROMANIA_NOFIRE, num_bp, one_in(), overmap_buffer, pos(), primary_weapon(), rem_morale(), Creature::remove_effect(), temp_conv, temp_corrected_by_climate_control(), temp_cur, temp_equalizer(), map::ter(), overmapbuffer::ter(), body_part_set::test(), TFLAG_DEEP_WATER, TFLAG_SWIMMABLE, body_part_type::token, trait_BARK, trait_DEBUG_NOTEMP, trait_M_SKIN2, trait_M_SKIN3, trait_PYROMANIA, trait_SHELL2, calendar::turn, map::veh_at(), item::volume(), wake_up(), warmth::wind_resistance_from_clothing(), and worn.

Referenced by game::do_turn(), and iuse_transform::use().

◆ update_fuel_storage()

void Character::update_fuel_storage ( const itype_id fuel)

Updates which bionic contain fuel and which is empty.

Definition at line 2069 of file character.cpp.

2070{
2071 const item it( fuel );
2072 if( get_value( fuel.str() ).empty() ) {
2073 for( const bionic_id &bid : get_bionic_fueled_with( it ) ) {
2074 remove_value( bid.c_str() );
2075 }
2076 return;
2077 }
2078
2079 std::vector<bionic_id> bids = get_bionic_fueled_with( it );
2080 if( bids.empty() ) {
2081 return;
2082 }
2083 int amount_fuel_loaded = std::stoi( get_value( fuel.str() ) );
2084 std::vector<bionic_id> loaded_bio;
2085
2086 // Sort bionic in order of decreasing capacity
2087 // To fill the bigger ones firts.
2088 bool swap = true;
2089 while( swap ) {
2090 swap = false;
2091 for( size_t i = 0; i < bids.size() - 1; i++ ) {
2092 if( bids[i + 1]->fuel_capacity > bids[i]->fuel_capacity ) {
2093 std::swap( bids[i + 1], bids[i] );
2094 swap = true;
2095 }
2096 }
2097 }
2098
2099 for( const bionic_id &bid : bids ) {
2100 remove_value( bid.c_str() );
2101 if( bid->fuel_capacity <= amount_fuel_loaded ) {
2102 amount_fuel_loaded -= bid->fuel_capacity;
2103 loaded_bio.emplace_back( bid );
2104 } else if( amount_fuel_loaded != 0 ) {
2105 loaded_bio.emplace_back( bid );
2106 break;
2107 }
2108 }
2109
2110 for( const bionic_id &bd : loaded_bio ) {
2111 set_value( bd.str(), fuel.str() );
2112 }
2113
2114}
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496

References get_bionic_fueled_with(), Creature::get_value(), Creature::remove_value(), Creature::set_value(), string_id< T >::str(), and cata::swap().

Referenced by burn_fuel(), fuel_bionic_with(), and suffer_from_radiation().

◆ update_health()

void Character::update_health ( int  external_modifiers = 0)
virtual

Handles health fluctuations over time.

Definition at line 4659 of file character.cpp.

4660{
4661 if( has_artifact_with( AEP_SICK ) ) {
4662 // Carrying a sickness artifact makes your health 50 points worse on average
4663 external_modifiers -= 50;
4664 }
4665 // Limit healthy_mod to [-200, 200].
4666 // This also sets approximate bounds for the character's health.
4667 if( get_healthy_mod() > get_max_healthy() ) {
4669 } else if( get_healthy_mod() < -200 ) {
4670 set_healthy_mod( -200 );
4671 }
4672
4673 // Active leukocyte breeder will keep your health near 100
4674 int effective_healthy_mod = get_healthy_mod();
4676 // Side effect: dependency
4677 mod_healthy_mod( -50, -200 );
4678 effective_healthy_mod = 100;
4679 }
4680
4681 // Health tends toward healthy_mod.
4682 // For small differences, it changes 4 points per day
4683 // For large ones, up to ~40% of the difference per day
4684 int health_change = effective_healthy_mod - get_healthy() + external_modifiers;
4685 mod_healthy( sgn( health_change ) * std::max( 1, std::abs( health_change ) / 10 ) );
4686
4687 // And healthy_mod decays over time.
4688 // Slowly near 0, but it's hard to overpower it near +/-100
4689 set_healthy_mod( std::round( get_healthy_mod() * 0.95f ) );
4690
4691 add_msg( m_debug, "Health: %d, Health mod: %d", get_healthy(), get_healthy_mod() );
4692}
static const bionic_id bio_leukocyte("bio_leukocyte")
int get_max_healthy() const
Definition: character.cpp:4568
@ AEP_SICK
Definition: enums.h:141

References add_msg(), AEP_SICK, bio_leukocyte, get_healthy(), get_healthy_mod(), get_max_healthy(), has_active_bionic(), has_artifact_with(), m_debug, mod_healthy(), mod_healthy_mod(), set_healthy_mod(), and sgn().

Referenced by update_body().

◆ update_morale()

void Character::update_morale ( )

Ticks down morale counters and removes them.

Definition at line 9007 of file character.cpp.

9008{
9009 morale->decay( 1_minutes );
9011}

References apply_persistent_morale(), and morale.

Referenced by process_turn().

◆ update_needs()

void Character::update_needs ( int  rate_multiplier)

Increases hunger, thirst, fatigue and stimulants wearing off.

rate_multiplier is for retroactive updates.

Definition at line 4811 of file character.cpp.

4812{
4813 const int current_stim = get_stim();
4814 // Hunger, thirst, & fatigue up every 5 minutes
4816 // No food/thirst/fatigue clock at all
4817 const bool debug_ls = has_trait( trait_DEBUG_LS );
4818 // No food/thirst, capped fatigue clock (only up to tired)
4819 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4820 const bool asleep = !sleep.is_null();
4821 const bool lying = asleep || has_effect( effect_lying_down ) ||
4823
4824 needs_rates rates = calc_needs_rates();
4825
4826 const bool wasnt_fatigued = get_fatigue() <= fatigue_levels::dead_tired;
4827 // Don't increase fatigue if sleeping or trying to sleep or if we're at the cap.
4828 if( get_fatigue() < 1050 && !asleep && !debug_ls ) {
4829 if( rates.fatigue > 0.0f ) {
4830 int fatigue_roll = roll_remainder( rates.fatigue * rate_multiplier );
4831 mod_fatigue( fatigue_roll );
4832
4833 // Synaptic regen bionic stops SD while awake and boosts it while sleeping
4835 // fatigue_roll should be around 1 - so the counter increases by 1 every minute on average,
4836 // but characters who need less sleep will also get less sleep deprived, and vice-versa.
4837
4838 // Note: Since needs are updated in 5-minute increments, we have to multiply the roll again by
4839 // 5. If rate_multiplier is > 1, fatigue_roll will be higher and this will work out.
4840 mod_sleep_deprivation( fatigue_roll * 5 );
4841 }
4842
4843 if( npc_no_food && get_fatigue() > fatigue_levels::tired ) {
4844 set_fatigue( static_cast<int>( fatigue_levels::tired ) );
4845 }
4846 if( npc_no_food ) {
4848 }
4849 }
4850 } else if( asleep && rates.recovery > 0.0f ) {
4851 int recovered = roll_remainder( rates.recovery * rate_multiplier );
4852 // Hibernation prevents waking up until you're hungry or thirsty
4853 if( get_fatigue() - recovered < -20 && !is_hibernating() ) {
4854 // Should be wake up, but that could prevent some retroactive regeneration
4855 sleep.set_duration( 1_turns );
4856 mod_fatigue( -25 );
4857 } else {
4859 recovered *= .5;
4860 }
4861 mod_fatigue( -recovered );
4862
4863 float rest_modifier = 1.0f;
4864 // Bionic doubles the base regen
4866 rest_modifier += 1.0f;
4867 }
4869 rest_modifier += 0.2f;
4870 }
4871
4872 const character_funcs::comfort_level comfort =
4874
4875 // Best possible bed increases recovery by 30% of base
4877 rest_modifier += 0.3f;
4878 } else if( comfort >= character_funcs::comfort_level::comfortable ) {
4879 rest_modifier += 0.2f;
4881 rest_modifier += 0.1f;
4882 }
4883
4884 // 6 hours of sleep per day will let you avoid deprivation
4885 // 4 hours if on great bed plus melatonin
4886 // Math: 5 (fatigue to minutes), 3 (1:3 sleep to waking),
4887 // 2 (legacy sleep non-linearity thing)
4888 mod_sleep_deprivation( -rest_modifier * ( recovered * 3.0f * 5.0f / 2.0f ) );
4889
4890 }
4891 }
4892 if( is_player() && wasnt_fatigued && get_fatigue() > fatigue_levels::dead_tired && !lying ) {
4893 if( !activity ) {
4894 add_msg_if_player( m_warning, _( "You're feeling tired. %s to lie down for sleep." ),
4895 press_x( ACTION_SLEEP ) );
4896 } else {
4897 g->cancel_activity_query( _( "You're feeling tired." ) );
4898 }
4899 }
4900
4901 if( current_stim < 0 ) {
4902 set_stim( std::min( current_stim + rate_multiplier, 0 ) );
4903 } else if( current_stim > 0 ) {
4904 set_stim( std::max( current_stim - rate_multiplier, 0 ) );
4905 }
4906
4907 if( get_painkiller() > 0 ) {
4908 mod_painkiller( -std::min( get_painkiller(), rate_multiplier ) );
4909 }
4910
4911 // Huge folks take penalties for cramming themselves in vehicles
4912 if( in_vehicle && ( get_size() == MS_HUGE )
4914 vehicle *veh = veh_pointer_or_null( get_map().veh_at( pos() ) );
4915 // it's painful to work the controls, but passengers in open topped vehicles are fine
4916 if( veh && ( veh->enclosed_at( pos() ) || veh->player_in_control( *this->as_player() ) ) ) {
4918 _( "You're cramping up from stuffing yourself in this vehicle." ) );
4919 if( is_npc() ) {
4920 npc &as_npc = dynamic_cast<npc &>( *this );
4921 as_npc.complain_about( "cramped_vehicle", 1_hours, "<cramped_vehicle>", false );
4922 }
4923
4924 mod_pain( rng( 4, 6 ) );
4925 focus_pool -= 1;
4926 }
4927 }
4928}
std::string press_x(action_id act)
Definition: action.cpp:465
@ ACTION_SLEEP
Open sleep menu.
Definition: action.h:205
static const efftype_id effect_melatonin_supplements("melatonin")
static const trait_id trait_DEBUG_LS("DEBUG_LS")
static const bionic_id bio_synaptic_regen("bio_synaptic_regen")
static const efftype_id effect_lying_down("lying_down")
needs_rates calc_needs_rates() const
Definition: character.cpp:4929
virtual void mod_sleep_deprivation(int nsleep_deprivation)
Definition: character.cpp:4460
virtual npc * as_npc()
Definition: creature.h:110
bool complain_about(const std::string &issue, const time_duration &dur, const std::string &speech, bool force=false, sounds::sound_t priority=sounds::sound_t::speech)
Definition: npcmove.cpp:4569
bool enclosed_at(const tripoint &pos)
Definition: vehicle.cpp:6308
comfort_response_t base_comfort_value(const Character &who, const tripoint &p)
Rate point's ability to serve as a bed.

References _, ACT_TRY_SLEEP, ACTION_SLEEP, activity, Creature::add_msg_if_player(), Creature::as_npc(), character_funcs::base_comfort_value(), bio_synaptic_regen, calc_needs_rates(), character_funcs::comfortable, npc::complain_about(), dead_tired, effect_lying_down, effect_melatonin_supplements, effect_narcosis, effect_recently_coughed, effect_sleep, vehicle::enclosed_at(), needs_rates::fatigue, focus_pool, g, Creature::get_effect(), get_fatigue(), get_map(), get_painkiller(), get_size(), get_stim(), has_active_bionic(), Creature::has_effect(), has_trait(), player_activity::id(), in_vehicle, is_hibernating(), Creature::is_npc(), Creature::is_player(), character_funcs::comfort_response_t::level, m_bad, m_warning, mod_fatigue(), mod_pain(), mod_painkiller(), mod_sleep_deprivation(), MS_HUGE, vehicle::player_in_control(), pos(), press_x(), needs_rates::recovery, rng(), roll_remainder(), set_fatigue(), set_sleep_deprivation(), set_stim(), sleep, character_funcs::slightly_comfortable, tired, trait_DEBUG_LS, trait_NOPAIN, veh_pointer_or_null(), and character_funcs::very_comfortable.

Referenced by update_body().

◆ update_stamina()

void Character::update_stamina ( int  turns)

Regenerates stamina.

Definition at line 7173 of file character.cpp.

7174{
7175 static const std::string player_base_stamina_regen_rate( "PLAYER_BASE_STAMINA_REGEN_RATE" );
7176 static const std::string stamina_regen_modifier( "stamina_regen_modifier" );
7177 const float base_regen_rate = get_option<float>( player_base_stamina_regen_rate );
7178 const int current_stim = get_stim();
7179 float stamina_recovery = 0.0f;
7180 // Recover some stamina every turn.
7181 // max stamina modifers from mutation also affect stamina multi
7182 float stamina_multiplier = 1.0f + mutation_value( stamina_regen_modifier ) +
7183 ( mutation_value( "max_stamina_modifier" ) - 1.0f ) +
7185 // But mouth encumbrance interferes, even with mutated stamina.
7186 stamina_recovery += stamina_multiplier * std::max( 1.0f,
7187 base_regen_rate - ( encumb( bp_mouth ) / 5.0f ) );
7188 // TODO: recovering stamina causes hunger/thirst/fatigue.
7189 // TODO: Tiredness slowing recovery
7190
7191 // stim recovers stamina (or impairs recovery)
7192 if( current_stim > 0 ) {
7193 // TODO: Make stamina recovery with stims cost health
7194 stamina_recovery += std::min( 5.0f, current_stim / 15.0f );
7195 } else if( current_stim < 0 ) {
7196 // Affect it less near 0 and more near full
7197 // Negative stim kill at -200
7198 // At -100 stim it inflicts -20 malus to regen at 100% stamina,
7199 // effectivly countering stamina gain of default 20,
7200 // at 50% stamina its -10 (50%), cuts by 25% at 25% stamina
7201 // FIXME: this formula is only suitable for advancing by 1 turn
7202 stamina_recovery += current_stim / 5.0f * get_stamina() / get_stamina_max();
7203 }
7204 stamina_recovery = std::max( 0.0f, stamina_recovery );
7205
7206 const int max_stam = get_stamina_max();
7207 if( get_power_level() >= 3_kJ && has_active_bionic( bio_gills ) ) {
7208 int bonus = std::min<int>( units::to_kilojoule( get_power_level() ) / 3,
7209 max_stam - get_stamina() - stamina_recovery * turns );
7210 // so the effective recovery is up to 5x default
7211 bonus = std::min( bonus, 4 * static_cast<int>( base_regen_rate ) );
7212 if( bonus > 0 ) {
7213 stamina_recovery += bonus;
7214 bonus /= 10;
7215 bonus = std::max( bonus, 1 );
7217 }
7218 }
7219
7220 mod_stamina( roll_remainder( stamina_recovery * turns ) );
7221 add_msg( m_debug, "Stamina recovery: %d", roll_remainder( stamina_recovery * turns ) );
7222 // Cap at max
7223 set_stamina( std::min( std::max( get_stamina(), 0 ), max_stam ) );
7224}
static const bionic_id bio_gills("bio_gills")

References add_msg(), bio_gills, bonus_from_enchantments(), bp_mouth, encumb(), units::from_kilojoule(), get_power_level(), get_stamina(), get_stamina_max(), get_stim(), has_active_bionic(), m_debug, mod_power_level(), mod_stamina(), mutation_value(), roll_remainder(), set_stamina(), enchant_vals::STAMINA_REGEN, and units::to_kilojoule().

Referenced by update_body().

◆ update_stomach()

void Character::update_stomach ( const time_point from,
const time_point to 
)

Updates the stomach to give accurate hunger messages.

Definition at line 4768 of file character.cpp.

4769{
4770 const needs_rates rates = calc_needs_rates();
4771 // No food/thirst/fatigue clock at all
4772 const bool debug_ls = has_trait( trait_DEBUG_LS );
4773 // No food/thirst, capped fatigue clock (only up to tired)
4774 const bool npc_no_food = is_npc() && get_option<bool>( "NO_NPC_FOOD" );
4775 const bool foodless = debug_ls || npc_no_food;
4776 const bool mouse = has_trait( trait_NO_THIRST );
4777 const bool mycus = has_trait( trait_M_DEPENDENT );
4778 const float kcal_per_time = bmr() / ( 12.0f * 24.0f );
4779 const int five_mins = ticks_between( from, to, 5_minutes );
4780
4781 if( five_mins > 0 ) {
4782 // Digest nutrients in stomach
4783 food_summary digested_to_body = stomach.digest( rates, five_mins );
4784 // Apply nutrients, unless this is an NPC and NO_NPC_FOOD is enabled.
4785 if( !npc_no_food ) {
4786 mod_stored_kcal( digested_to_body.nutr.kcal );
4787 vitamins_mod( digested_to_body.nutr.vitamins, false );
4788 }
4789 if( !foodless && rates.hunger > 0.0f ) {
4790 // instead of hunger keeping track of how you're living, burn calories instead
4791 mod_stored_kcal( -roll_remainder( five_mins * kcal_per_time ) );
4792 }
4793 }
4794
4795 if( !foodless && rates.thirst > 0.0f ) {
4796 mod_thirst( roll_remainder( rates.thirst * five_mins ) );
4797 }
4798
4799 if( npc_no_food ) {
4800 set_thirst( static_cast<int>( thirst_levels::hydrated ) );
4802 }
4803
4804 // Mycus and Metabolic Rehydration makes thirst unnecessary
4805 // since water is not limited by intake but by absorption, we can just set thirst to zero
4806 if( mycus || mouse ) {
4807 set_thirst( 0 );
4808 }
4809}
static const trait_id trait_NO_THIRST("NO_THIRST")
static const trait_id trait_M_DEPENDENT("M_DEPENDENT")
void vitamins_mod(const std::map< vitamin_id, int > &, bool capped=true)
food_summary digest(const needs_rates &metabolic_rates, int five_mins)
Processes food and outputs nutrients that are finished processing Metabolic rates are required becaus...
Definition: stomach.cpp:132
int mycus(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:1442
nutrients nutr
Definition: stomach.h:53
std::map< vitamin_id, int > vitamins
vitamins potentially provided by this comestible (if any)
Definition: stomach.h:21

References bmr(), calc_needs_rates(), stomach_contents::digest(), has_trait(), needs_rates::hunger, hydrated, Creature::is_npc(), nutrients::kcal, max_stored_kcal(), mod_stored_kcal(), mod_thirst(), iuse::mycus(), food_summary::nutr, roll_remainder(), set_stored_kcal(), set_thirst(), stomach, needs_rates::thirst, ticks_between(), trait_DEBUG_LS, trait_M_DEPENDENT, trait_NO_THIRST, nutrients::vitamins, and vitamins_mod().

Referenced by update_body().

◆ update_type_of_scent() [1/2]

void Character::update_type_of_scent ( bool  init = false)

Definition at line 8733 of file character.cpp.

8734{
8735 scenttype_id new_scent = scenttype_id( "sc_human" );
8736 for( const trait_id &mut : get_mutations() ) {
8737 if( mut.obj().scent_typeid ) {
8738 new_scent = mut.obj().scent_typeid.value();
8739 }
8740 }
8741
8742 if( !init && new_scent != get_type_of_scent() ) {
8743 g->scent.reset();
8744 }
8745 set_type_of_scent( new_scent );
8746}
scenttype_id get_type_of_scent() const
Definition: character.cpp:8766
Definition: init.h:182

References g, get_mutations(), get_type_of_scent(), mutation_branch::scent_typeid, and set_type_of_scent().

Referenced by on_mutation_gain(), on_mutation_loss(), and update_type_of_scent().

◆ update_type_of_scent() [2/2]

void Character::update_type_of_scent ( const trait_id mut,
bool  gain = true 
)

Definition at line 8748 of file character.cpp.

8749{
8750 const std::optional<scenttype_id> &mut_scent = mut->scent_typeid;
8751 if( mut_scent ) {
8752 if( gain && mut_scent.value() != get_type_of_scent() ) {
8753 set_type_of_scent( mut_scent.value() );
8754 g->scent.reset();
8755 } else {
8757 }
8758 }
8759}
std::optional< scenttype_id > scent_typeid
What do you smell like.
Definition: mutation.h:161

References g, get_type_of_scent(), mutation_branch::scent_typeid, set_type_of_scent(), and update_type_of_scent().

◆ update_vitamins()

void Character::update_vitamins ( const vitamin_id vit)

Set vitamin deficiency/excess disease states dependent upon current vitamin levels.

Definition at line 8807 of file character.cpp.

8808{
8809 if( is_npc() ) {
8810 return; // NPCs cannot develop vitamin diseases
8811 }
8812
8813 efftype_id def = vit.obj().deficiency();
8814 efftype_id exc = vit.obj().excess();
8815
8816 int lvl = vit.obj().severity( vitamin_get( vit ) );
8817 if( lvl <= 0 ) {
8818 remove_effect( def );
8819 }
8820 if( lvl >= 0 ) {
8821 remove_effect( exc );
8822 }
8823 if( lvl > 0 ) {
8824 if( has_effect( def, num_bp ) ) {
8825 get_effect( def, num_bp ).set_intensity( lvl, true );
8826 } else {
8827 add_effect( def, 1_turns, num_bp, lvl );
8828 }
8829 }
8830 if( lvl < 0 ) {
8831 if( has_effect( exc, num_bp ) ) {
8832 get_effect( exc, num_bp ).set_intensity( -lvl, true );
8833 } else {
8834 add_effect( exc, 1_turns, num_bp, -lvl );
8835 }
8836 }
8837}
int vitamin_get(const vitamin_id &vit) const
Check current level of a vitamin.
int set_intensity(int val, bool alert=false)
Sets intensity of effect capped by range [1..max_intensity].
Definition: effect.cpp:858
const efftype_id & deficiency() const
Disease effect with increasing intensity proportional to vitamin deficiency.
Definition: vitamin.h:57
const efftype_id & excess() const
Disease effect with increasing intensity proportional to vitamin excess.
Definition: vitamin.h:62
int severity(int qty) const
Get intensity of deficiency or zero if not deficient for specified qty.
Definition: vitamin.cpp:39

References Creature::add_effect(), vitamin::deficiency(), vitamin::excess(), Creature::get_effect(), Creature::has_effect(), Creature::is_npc(), num_bp, string_id< T >::obj(), Creature::remove_effect(), effect::set_intensity(), vitamin::severity(), and vitamin_get().

Referenced by vitamin_mod().

◆ use_amount()

std::list< item > Character::use_amount ( itype_id  it,
int  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9636 of file character.cpp.

9638{
9639 std::list<item> ret;
9640 if( primary_weapon().use_amount( it, quantity, ret ) ) {
9641 remove_weapon();
9642 }
9643 for( auto a = worn.begin(); a != worn.end() && quantity > 0; ) {
9644 if( a->use_amount( it, quantity, ret, filter ) ) {
9645 a->on_takeoff( *this );
9646 a = worn.erase( a );
9647 } else {
9648 ++a;
9649 }
9650 }
9651 if( quantity <= 0 ) {
9652 return ret;
9653 }
9654 std::list<item> tmp = inv.use_amount( it, quantity, filter );
9655 ret.splice( ret.end(), tmp );
9656 return ret;
9657}
std::list< item > use_amount(itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: character.cpp:9636
std::list< item > use_amount(itype_id it, int quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: inventory.cpp:856

References a, inv, primary_weapon(), remove_weapon(), cata::hash64_detail::ret, use_amount(), inventory::use_amount(), and worn.

Referenced by computer_session::action_srcf_elevator(), iexamine::cardreader(), iexamine::cardreader_robofac(), player::consume_items(), game::find_or_make_stairs(), hack_attempt(), monexamine::mech_hack(), iexamine::pedestal_temple(), activity_handlers::plant_seed_finish(), vehicle::reload_seeds(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), sinkhole_safety_roll(), npc_trading::transfer_items(), and use_amount().

◆ use_charges()

std::list< item > Character::use_charges ( const itype_id what,
int  qty,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 9668 of file character.cpp.

9670{
9671 std::list<item> res;
9672
9673 if( qty <= 0 ) {
9674 return res;
9675
9676 } else if( what == itype_toolset ) {
9678 return res;
9679
9680 } else if( what == itype_fire ) {
9681 use_fire( qty );
9682 return res;
9683
9684 } else if( what == itype_bio_armor ) {
9685 float mod_qty = 0;
9686 float efficiency = 1;
9687 for( const bionic &bio : *my_bionics ) {
9688 if( bio.powered && bio.info().has_flag( flag_BIONIC_ARMOR_INTERFACE ) ) {
9689 efficiency = std::max( efficiency, bio.info().fuel_efficiency );
9690 }
9691 }
9692 if( efficiency == 1 ) {
9693 debugmsg( "Player lacks a bionic armor interface with fuel efficiency field." );
9694 }
9695 mod_qty = qty / efficiency;
9697 return res;
9698
9699 } else if( what == itype_UPS ) {
9700 if( is_mounted() && mounted_creature.get()->has_flag( MF_RIDEABLE_MECH ) &&
9701 mounted_creature.get()->battery_item ) {
9702 auto mons = mounted_creature.get();
9703 int power_drain = std::min( mons->battery_item->ammo_remaining(), qty );
9704 mons->use_mech_power( -power_drain );
9705 qty -= std::min( qty, power_drain );
9706 return res;
9707 }
9708 if( has_power() && has_active_bionic( bio_ups ) ) {
9709 int bio = std::min( units::to_kilojoule( get_power_level() ), qty );
9711 qty -= std::min( qty, bio );
9712 }
9713
9714 int adv = charges_of( itype_adv_UPS_off, static_cast<int>( std::ceil( qty * 0.6 ) ) );
9715 if( adv > 0 ) {
9716 std::list<item> found = use_charges( itype_adv_UPS_off, adv );
9717 res.splice( res.end(), found );
9718 qty -= std::min( qty, static_cast<int>( adv / 0.6 ) );
9719 }
9720
9721 int ups = charges_of( itype_UPS_off, qty );
9722 if( ups > 0 ) {
9723 std::list<item> found = use_charges( itype_UPS_off, ups );
9724 res.splice( res.end(), found );
9725 qty -= std::min( qty, ups );
9726 }
9727 return res;
9728
9729 }
9730
9731 std::vector<item *> del;
9732
9733 bool has_tool_with_UPS = false;
9734 visit_items( [this, &what, &qty, &res, &del, &has_tool_with_UPS, &filter]( item * e ) {
9735 if( e->use_charges( what, qty, res, pos(), filter ) ) {
9736 del.push_back( e );
9737 }
9738 if( filter( *e ) && e->typeId() == what && e->has_flag( flag_USE_UPS ) ) {
9739 has_tool_with_UPS = true;
9740 }
9741 return qty > 0 ? VisitResponse::SKIP : VisitResponse::ABORT;
9742 } );
9743
9744 for( auto e : del ) {
9745 remove_item( *e );
9746 }
9747
9748 if( has_tool_with_UPS ) {
9749 use_charges( itype_UPS, qty );
9750 }
9751
9752 return res;
9753}
static const itype_id itype_toolset("toolset")
static const itype_id itype_adv_UPS_off("adv_UPS_off")
static const bionic_id bio_ups("bio_ups")
static const itype_id itype_UPS_off("UPS_off")
void use_fire(int quantity)
Definition: character.cpp:9819
bool use_charges(const itype_id &what, int &qty, std::list< item > &used, const tripoint &pos, const std::function< bool(const item &)> &filter=return_true< item >)
Consumes specified charges (or fewer) from this and any contained items.
Definition: item.cpp:8617

References ABORT, bio_ups, visitable< Character >::charges_of(), debugmsg, flag_BIONIC_ARMOR_INTERFACE, flag_USE_UPS(), units::from_kilojoule(), get_power_level(), has_active_bionic(), item::has_flag(), has_power(), is_mounted(), itype_adv_UPS_off, itype_bio_armor, itype_fire, itype_toolset, itype_UPS, itype_UPS_off, MF_RIDEABLE_MECH, mod_power_level(), mounted_creature, my_bionics, pos(), visitable< Character >::remove_item(), SKIP, units::to_kilojoule(), item::typeId(), item::use_charges(), use_charges(), use_fire(), and visitable< Character >::visit_items().

Referenced by iexamine::arcfurnace_empty(), consume_charges(), player::consume_items(), consume_med(), consume_remote_fuel(), player::consume_tools(), eat(), iuse::ecig(), iexamine::fertilize_plant(), ranged::fire_gun(), iexamine::fireplace(), iexamine::fvat_empty(), activity_handlers::gunmod_add_finish(), hack_attempt(), iexamine::keg(), iexamine::kiln_empty(), monexamine::pay_bot(), iexamine::pay_gas(), activity_handlers::plant_seed_finish(), process_items(), iexamine::reload_furniture(), vehicle::reload_seeds(), talk_effect_fun_t::set_bulk_trade_accept(), talk_effect_fun_t::set_consume_item(), talk_effect_fun_t::set_u_sell_item(), smoker_activate(), npc_trading::transfer_items(), try_consume(), try_start_hacking(), consume_drug_iuse::use(), place_monster_iuse::use(), cauterize_actor::use(), use_charges(), use_charges_if_avail(), use_fire(), and iexamine::vending().

◆ use_charges_if_avail()

bool Character::use_charges_if_avail ( const itype_id it,
int  quantity 
)

Definition at line 9659 of file character.cpp.

9660{
9661 if( has_charges( it, quantity ) ) {
9662 use_charges( it, quantity );
9663 return true;
9664 }
9665 return false;
9666}

References has_charges(), and use_charges().

Referenced by iuse::arrow_flammable(), iuse::firecracker(), activity_handlers::game_do_turn(), iuse::meth(), iuse::note_bionics(), item::process_tool(), item::reload(), iuse::smoking(), suffer_from_asthma(), and iuse_transform::use().

◆ use_fire()

void Character::use_fire ( int  quantity)

Definition at line 9819 of file character.cpp.

9820{
9821 //Okay, so checks for nearby fires first,
9822 //then held lit torch or candle, bionic tool/lighter/laser
9823 //tries to use 1 charge of lighters, matches, flame throwers
9824 //If there is enough power, will use power of one activation of the bio_lighter, bio_tools and bio_laser
9825 // (home made, military), hotplate, welder in that order.
9826 // bio_lighter, bio_laser, bio_tools, has_active_bionic("bio_tools"
9827
9828 if( get_map().has_nearby_fire( pos() ) ) {
9829 return;
9830 } else if( has_item_with_flag( "FIRE" ) ) {
9831 return;
9832 } else if( has_item_with_flag( "FIRESTARTER" ) ) {
9833 auto firestarters = all_items_with_flag( "FIRESTARTER" );
9834 for( auto &i : firestarters ) {
9835 if( has_charges( i->typeId(), quantity ) ) {
9836 use_charges( i->typeId(), quantity );
9837 return;
9838 }
9839 }
9840 } else if( has_active_bionic( bio_tools ) && get_power_level() > quantity * 5_kJ ) {
9841 mod_power_level( -quantity * 5_kJ );
9842 return;
9843 } else if( has_bionic( bio_lighter ) && get_power_level() > quantity * 5_kJ ) {
9844 mod_power_level( -quantity * 5_kJ );
9845 return;
9846 } else if( has_bionic( bio_laser ) && get_power_level() > quantity * 5_kJ ) {
9847 mod_power_level( -quantity * 5_kJ );
9848 return;
9849 }
9850}

References all_items_with_flag(), bio_laser, bio_lighter, bio_tools, get_map(), get_power_level(), has_active_bionic(), has_bionic(), has_charges(), has_item_with_flag(), mod_power_level(), pos(), and use_charges().

Referenced by use_charges().

◆ used_weapon() [1/2]

item & Character::used_weapon ( )

Legacy code hack, don't use.

Returns the null item if martial art forces unarmed, otherwise primary_weapon. Use wielded_items instead.

Definition at line 145 of file melee.cpp.

146{
147 return const_cast<item &>( const_cast<const Character *>( this )->used_weapon() );
148}

References used_weapon().

Referenced by get_melee_hit_base(), melee_attack(), unarmed_attack(), and used_weapon().

◆ used_weapon() [2/2]

const item & Character::used_weapon ( ) const

Definition at line 140 of file melee.cpp.

141{
142 return martial_arts_data->selected_force_unarmed() ? null_item_reference() : primary_weapon();
143}

References martial_arts_data, null_item_reference(), and primary_weapon().

◆ valid_aoe_technique() [1/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique 
)
private

Check if an area-of-effect technique has valid targets.

Definition at line 1277 of file melee.cpp.

1278{
1279 std::vector<Creature *> dummy_targets;
1280 return valid_aoe_technique( t, technique, dummy_targets );
1281}

References valid_aoe_technique().

Referenced by perform_technique(), pick_technique(), and valid_aoe_technique().

◆ valid_aoe_technique() [2/2]

bool Character::valid_aoe_technique ( Creature t,
const ma_technique technique,
std::vector< Creature * > &  targets 
)
private

Definition at line 1283 of file melee.cpp.

1285{
1286 if( technique.aoe.empty() ) {
1287 return false;
1288 }
1289
1290 // pre-computed matrix of adjacent squares
1291 std::array<int, 9> offset_a = { {0, -1, -1, 1, 0, -1, 1, 1, 0 } };
1292 std::array<int, 9> offset_b = { {-1, -1, 0, -1, 0, 1, 0, 1, 1 } };
1293
1294 // filter the values to be between -1 and 1 to avoid indexing the array out of bounds
1295 int dy = std::max( -1, std::min( 1, t.posy() - posy() ) );
1296 int dx = std::max( -1, std::min( 1, t.posx() - posx() ) );
1297 int lookup = dy + 1 + 3 * ( dx + 1 );
1298
1299 //wide hits all targets adjacent to the attacker and the target
1300 if( technique.aoe == "wide" ) {
1301 //check if either (or both) of the squares next to our target contain a possible victim
1302 //offsets are a pre-computed matrix allowing us to quickly lookup adjacent squares
1303 tripoint left = pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1304 tripoint right = pos() + tripoint( offset_b[lookup], -offset_a[lookup], 0 );
1305
1306 monster *const mon_l = g->critter_at<monster>( left );
1307 if( mon_l && mon_l->friendly == 0 ) {
1308 targets.push_back( mon_l );
1309 }
1310 monster *const mon_r = g->critter_at<monster>( right );
1311 if( mon_r && mon_r->friendly == 0 ) {
1312 targets.push_back( mon_r );
1313 }
1314
1315 npc *const npc_l = g->critter_at<npc>( left );
1316 npc *const npc_r = g->critter_at<npc>( right );
1317 if( npc_l && npc_l->is_enemy() ) {
1318 targets.push_back( npc_l );
1319 }
1320 if( npc_r && npc_r->is_enemy() ) {
1321 targets.push_back( npc_r );
1322 }
1323 if( !targets.empty() ) {
1324 return true;
1325 }
1326 }
1327
1328 if( technique.aoe == "impale" ) {
1329 // Impale hits the target and a single target behind them
1330 // Check if the square cardinally behind our target, or to the left / right,
1331 // contains a possible target.
1332 tripoint left = t.pos() + tripoint( offset_a[lookup], offset_b[lookup], 0 );
1333 tripoint target_pos = t.pos() + ( t.pos() - pos() );
1334 tripoint right = t.pos() + tripoint( offset_b[lookup], -offset_b[lookup], 0 );
1335
1336 monster *const mon_l = g->critter_at<monster>( left );
1337 monster *const mon_t = g->critter_at<monster>( target_pos );
1338 monster *const mon_r = g->critter_at<monster>( right );
1339 if( mon_l && mon_l->friendly == 0 ) {
1340 targets.push_back( mon_l );
1341 }
1342 if( mon_t && mon_t->friendly == 0 ) {
1343 targets.push_back( mon_t );
1344 }
1345 if( mon_r && mon_r->friendly == 0 ) {
1346 targets.push_back( mon_r );
1347 }
1348
1349 npc *const npc_l = g->critter_at<npc>( left );
1350 npc *const npc_t = g->critter_at<npc>( target_pos );
1351 npc *const npc_r = g->critter_at<npc>( right );
1352 if( npc_l && npc_l->is_enemy() ) {
1353 targets.push_back( npc_l );
1354 }
1355 if( npc_t && npc_t->is_enemy() ) {
1356 targets.push_back( npc_t );
1357 }
1358 if( npc_r && npc_r->is_enemy() ) {
1359 targets.push_back( npc_r );
1360 }
1361 if( !targets.empty() ) {
1362 return true;
1363 }
1364 }
1365
1366 if( targets.empty() && technique.aoe == "spin" ) {
1367 for( const tripoint &tmp : g->m.points_in_radius( pos(), 1 ) ) {
1368 if( tmp == t.pos() ) {
1369 continue;
1370 }
1371 monster *const mon = g->critter_at<monster>( tmp );
1372 if( mon && mon->friendly == 0 ) {
1373 targets.push_back( mon );
1374 }
1375 npc *const np = g->critter_at<npc>( tmp );
1376 if( np && np->is_enemy() ) {
1377 targets.push_back( np );
1378 }
1379 }
1380 //don't trigger circle for fewer than 2 targets
1381 if( targets.size() < 2 ) {
1382 targets.clear();
1383 } else {
1384 return true;
1385 }
1386 }
1387 return false;
1388}
bool is_enemy() const
Definition: npc.cpp:2047

References ma_technique::aoe, monster::friendly, g, npc::is_enemy(), left, Creature::pos(), pos(), Creature::posx(), posx(), Creature::posy(), posy(), and right.

◆ visibility()

int Character::visibility ( bool  check_color = false,
int  stillness = 0 
) const

Checks is_invisible() as well as other factors.

Definition at line 6298 of file character.cpp.

6299{
6300 // 0-100 %
6301 if( is_invisible() ) {
6302 return 0;
6303 }
6304 // TODO:
6305 // if ( dark_clothing() && light check ...
6306 int stealth_modifier = std::floor( mutation_value( "stealth_modifier" ) );
6307 return clamp( 100 - stealth_modifier, 40, 160 );
6308}
bool is_invisible() const
Definition: character.cpp:6288

References clamp(), is_invisible(), and mutation_value().

◆ visible_mutations()

std::string Character::visible_mutations ( int  visibility_cap) const

Returns an enumeration of visible mutations with colors.

Definition at line 1728 of file mutation.cpp.

1729{
1730 const std::vector<trait_id> &my_muts = get_mutations();
1731 const std::string trait_str = enumerate_as_string( my_muts.begin(), my_muts.end(),
1732 [visibility_cap ]( const trait_id & pr ) -> std::string {
1733 const auto &mut_branch = pr.obj();
1734 // Finally some use for visibility trait of mutations
1735 if( mut_branch.visibility > 0 && mut_branch.visibility >= visibility_cap )
1736 {
1737 return colorize( mut_branch.name(), mut_branch.get_display_color() );
1738 }
1739
1740 return std::string();
1741 } );
1742 return trait_str;
1743}

References enumerate_as_string(), and get_mutations().

Referenced by npc::print_info(), and short_description_parts().

◆ vitamin_get()

int Character::vitamin_get ( const vitamin_id vit) const

Check current level of a vitamin.

Accesses level of a given vitamin. If the vitamin_id specified does not exist then this function simply returns 0.

Parameters
vitID of vitamin to check level for.
Returns
current level for specified vitamin

Definition at line 580 of file consumption.cpp.

581{
582 if( get_option<bool>( "NO_VITAMINS" ) && vit->type() == vitamin_type::VITAMIN ) {
583 return 0;
584 }
585
586 const auto &v = vitamin_levels.find( vit );
587 return v != vitamin_levels.end() ? v->second : 0;
588}
const vitamin_type & type() const
Definition: vitamin.h:40
@ VITAMIN
Definition: vitamin.h:19

References vitamin::type(), VITAMIN, and vitamin_levels.

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and update_vitamins().

◆ vitamin_mod()

int Character::vitamin_mod ( const vitamin_id vit,
int  qty,
bool  capped = true 
)

Add or subtract vitamins from character storage pools.

Parameters
vitID of vitamin to modify
qtyamount by which to adjust vitamin (negative values are permitted)
cappedif true prevent vitamins which can accumulate in excess from doing so
Returns
adjusted level for the vitamin or zero if vitamin does not exist

Definition at line 548 of file consumption.cpp.

549{
550 if( !vit.is_valid() ) {
551 debugmsg( "Vitamin with id %s does not exist, and cannot be modified", vit.str() );
552 return 0;
553 }
554 // What's going on here? Emplace returns either an iterator to the inserted
555 // item or, if it already exists, an iterator to the (unchanged) extant item
556 // (Okay, technically it returns a pair<iterator, bool>, the iterator is what we want)
557 auto it = vitamin_levels.emplace( vit, 0 ).first;
558 const vitamin &v = *it->first;
559
560 if( qty > 0 ) {
561 // Accumulations can never occur from food sources
562 it->second = std::min( it->second + qty, capped ? 0 : v.max() );
563 update_vitamins( vit );
564
565 } else if( qty < 0 ) {
566 it->second = std::max( it->second + qty, v.min() );
567 update_vitamins( vit );
568 }
569
570 return it->second;
571}
void update_vitamins(const vitamin_id &vit)
Set vitamin deficiency/excess disease states dependent upon current vitamin levels.
Definition: character.cpp:8807
int max() const
Upper bound for any accumulation of this vitamin.
Definition: vitamin.h:72
int min() const
Lower bound for deficiency of this vitamin.
Definition: vitamin.h:67

References debugmsg, string_id< T >::is_valid(), vitamin::max(), vitamin::min(), string_id< T >::str(), update_vitamins(), and vitamin_levels.

Referenced by eff_fun_bleed(), rooted(), suffer_from_other_mutations(), suffer_in_sunlight(), update_body(), consume_drug_iuse::use(), vitamin_set(), and vitamins_mod().

◆ vitamin_rate()

time_duration Character::vitamin_rate ( const vitamin_id vit) const

Get vitamin usage rate (minutes per unit) accounting for bionics, mutations and effects.

Definition at line 533 of file consumption.cpp.

534{
535 time_duration res = vit.obj().rate();
536
537 for( const auto &m : get_mutations() ) {
538 const auto &mut = m.obj();
539 auto iter = mut.vitamin_rates.find( vit );
540 if( iter != mut.vitamin_rates.end() ) {
541 res += iter->second;
542 }
543 }
544
545 return res;
546}
time_duration rate() const
Usage rate of vitamin (time to consume unit) Lower bound is zero whereby vitamin is not required (but...
Definition: vitamin.h:80

References get_mutations(), string_id< T >::obj(), and vitamin::rate().

Referenced by item::food_info(), update_body(), and consume_drug_iuse::use().

◆ vitamin_set()

bool Character::vitamin_set ( const vitamin_id vit,
int  qty 
)

Sets level of a vitamin or returns false if id given in vit does not exist.

Note
status effects are still set for deficiency/excess
Parameters
[in]vitID of vitamin to adjust quantity for
[in]qtyQuantity to set level to
Returns
false if given vitamin_id does not exist, otherwise true

Definition at line 590 of file consumption.cpp.

591{
592 auto v = vitamin_levels.find( vit );
593 if( v == vitamin_levels.end() ) {
594 return false;
595 }
596 vitamin_mod( vit, qty - v->second, false );
597
598 return true;
599}

References vitamin_levels, and vitamin_mod().

Referenced by debug_menu::character_edit_menu(), eff_fun_mutating(), and eff_fun_toxin_buildup().

◆ vitamins_mod()

void Character::vitamins_mod ( const std::map< vitamin_id, int > &  vitamins,
bool  capped = true 
)

Definition at line 573 of file consumption.cpp.

574{
575 for( auto vit : vitamins ) {
576 vitamin_mod( vit.first, vit.second, capped );
577 }
578}

References vitamin_mod().

Referenced by update_stomach().

◆ volume_capacity()

◆ volume_capacity_reduced_by()

units::volume Character::volume_capacity_reduced_by ( const units::volume mod,
const excluded_stacks without = {} 
) const

Definition at line 2676 of file character.cpp.

2678{
2680 return units::volume_max;
2681 }
2682
2684 for( const auto &i : worn ) {
2685 if( !without.count( &i ) ) {
2686 ret += i.get_storage();
2687 }
2688 }
2689 if( has_bionic( bio_storage ) ) {
2690 ret += 2_liter;
2691 }
2692 if( has_trait( trait_SHELL ) ) {
2693 ret += 4_liter;
2694 }
2696 ret += 6_liter;
2697 }
2698 if( has_trait( trait_PACKMULE ) ) {
2699 ret = ret * 1.4;
2700 }
2701 if( has_trait( trait_DISORGANIZED ) ) {
2702 ret = ret * 0.6;
2703 }
2704 return std::max( ret, 0_ml );
2705}
static const trait_id trait_SHELL("SHELL")
static const trait_id trait_DISORGANIZED("DISORGANIZED")
static const trait_id trait_PACKMULE("PACKMULE")
static const bionic_id bio_storage("bio_storage")
const volume volume_max
Definition: units_volume.h:21

References bio_storage, has_active_mutation(), has_bionic(), has_trait(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, trait_DISORGANIZED, trait_PACKMULE, trait_SHELL, trait_SHELL2, units::volume_max, and worn.

Referenced by inventory_drop_selector::get_raw_stats(), pickup::reorder_for_dropping(), takeoff(), and volume_capacity().

◆ volume_carried()

◆ volume_carried_reduced_by()

units::volume Character::volume_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2618 of file character.cpp.

2619{
2620 if( without.empty() ) {
2621 return inv.volume();
2622 } else {
2623 return inv.volume_without( without );
2624 }
2625}
units::volume volume_without(const excluded_stacks &without) const
Definition: inventory.cpp:1072

References inv, inventory::volume(), and inventory::volume_without().

Referenced by inventory_drop_selector::get_raw_stats().

◆ vomit()

void Character::vomit ( )

Handles Character vomiting effects.

Definition at line 7704 of file character.cpp.

7705{
7706 g->events().send<event_type::throws_up>( getID() );
7707
7708 map &here = get_map();
7709 if( get_effect_int( effect_fungus ) >= 3 ) {
7710 add_msg_player_or_npc( m_bad, _( "You vomit thousands of live spores!" ),
7711 _( "<npcname> vomits thousands of live spores!" ) );
7712 fungal_effects( *g, here ).fungalize( pos(), this );
7713 } else if( stomach.get_calories() > 0 || get_thirst() < 0 ) {
7714 add_msg_player_or_npc( m_bad, _( "You throw up heavily!" ), _( "<npcname> throws up heavily!" ) );
7715 here.add_field( character_funcs::pick_safe_adjacent_tile( *this ).value_or( pos() ), fd_bile, 1 );
7716 } else {
7717 return;
7718 }
7719
7720 if( !has_effect( effect_nausea ) ) { // Prevents never-ending nausea
7721 const effect dummy_nausea( &effect_nausea.obj(), 0_turns, bodypart_str_id::NULL_ID(), 1,
7723 add_effect( effect_nausea, std::max( dummy_nausea.get_max_duration() *
7724 stomach.get_calories() / 100, dummy_nausea.get_int_dur_factor() ) );
7725 }
7726
7727 stomach.empty();
7728 set_thirst( std::max( 0, get_thirst() ) );
7730 if( get_healthy_mod() > 0 ) {
7731 set_healthy_mod( 0 );
7732 }
7733
7734 moves -= 100;
7735 // get_effect is more correct than has_effect because of body parts
7736 effect &eff_foodpoison = get_effect( effect_foodpoison );
7737 if( eff_foodpoison ) {
7738 eff_foodpoison.mod_duration( -30_minutes );
7739 }
7740 effect &eff_drunk = get_effect( effect_drunk );
7741 if( eff_drunk ) {
7742 eff_drunk.mod_duration( rng( -10_minutes, -50_minutes ) );
7743 }
7747 // Don't wake up when just retching
7748 wake_up();
7749}
static const efftype_id effect_fungus("fungus")
static const efftype_id effect_pkill2("pkill2")
static const efftype_id effect_bloated("bloated")
static const efftype_id effect_foodpoison("foodpoison")
static const efftype_id effect_pkill1("pkill1")
static const efftype_id effect_pkill3("pkill3")
void fungalize(const tripoint &p, Creature *origin=nullptr, double spore_chance=0.0)
field_type_id fd_bile
Definition: field_type.cpp:337
std::optional< tripoint > pick_safe_adjacent_tile(const Character &who)
Returns an unoccupied, safe adjacent point.

References _, Creature::add_effect(), Creature::add_msg_player_or_npc(), effect_bloated, effect_drunk, effect_foodpoison, effect_fungus, effect_nausea, effect_pkill1, effect_pkill2, effect_pkill3, stomach_contents::empty(), fd_bile, fungal_effects::fungalize(), g, stomach_contents::get_calories(), Creature::get_effect(), Creature::get_effect_int(), get_healthy_mod(), effect::get_int_dur_factor(), get_map(), effect::get_max_duration(), get_thirst(), getID(), Creature::has_effect(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), m_bad, effect::mod_duration(), Creature::moves, string_id< body_part_type >::NULL_ID(), string_id< T >::obj(), character_funcs::pick_safe_adjacent_tile(), pos(), Creature::remove_effect(), rng(), set_healthy_mod(), set_thirst(), stomach, throws_up, calendar::turn, and wake_up().

Referenced by activate_mutation(), addict_effect(), iuse::artifact(), iuse::blech(), iuse::dig(), eat(), eff_fun_hallu(), eff_fun_hot(), eff_fun_rat(), hardcoded_effects(), marloss_common(), iuse::mycus(), process_effects_internal(), process_one_effect(), iuse::sewage(), suffer_feral_kill_withdrawl(), suffer_from_radiation(), suffer_while_awake(), try_reject_mutagen(), avatar::vomit(), and spell_effect::vomit().

◆ wait_effects()

void Character::wait_effects ( )

Definition at line 1527 of file character.cpp.

1528{
1529 if( has_effect( effect_downed ) ) {
1530 try_remove_downed( *this );
1531 return;
1532 }
1533 if( has_effect( effect_beartrap ) ) {
1534 try_remove_bear_trap( *this );
1535 return;
1536 }
1537 if( has_effect( effect_lightsnare ) ) {
1538 try_remove_lightsnare( *this );
1539 return;
1540 }
1541 if( has_effect( effect_heavysnare ) ) {
1542 try_remove_heavysnare( *this );
1543 return;
1544 }
1545 if( has_effect( effect_webbed ) ) {
1546 try_remove_webs( *this );
1547 return;
1548 }
1549 if( has_effect( effect_grabbed ) ) {
1550 try_remove_grab( *this );
1551 return;
1552 }
1553}

References effect_beartrap, effect_downed, effect_grabbed, effect_heavysnare, effect_lightsnare, effect_webbed, Creature::has_effect(), try_remove_bear_trap(), try_remove_downed(), try_remove_grab(), try_remove_heavysnare(), try_remove_lightsnare(), and try_remove_webs().

Referenced by character_funcs::do_pause().

◆ wake_up()

void Character::wake_up ( )

Removes "sleep" and "lying_down".

Definition at line 7583 of file character.cpp.

7584{
7588 if( has_effect( effect_sleep ) ) {
7589 g->events().send<event_type::character_wakes_up>( getID() );
7591 // Wake up might be called more than once per turn, but we only need to recalc after removing sleep
7593 }
7594}
static const efftype_id effect_slept_through_alarm("slept_through_alarm")
static const efftype_id effect_alarm_clock("alarm_clock")
@ character_wakes_up

References character_wakes_up, effect_alarm_clock, effect_lying_down, effect_sleep, effect_slept_through_alarm, g, getID(), Creature::has_effect(), recalc_sight_limits(), and Creature::remove_effect().

Referenced by hardcoded_effects(), on_hurt(), sounds::process_sound_markers(), react_to_felt_pain(), Creature::remove_effect(), suffer_feral_kill_withdrawl(), suffer_from_asthma(), suffer_from_sunburn(), update_bodytemp(), vomit(), and avatar::wake_up().

◆ warmth()

std::map< bodypart_id, int > Character::warmth ( const std::map< bodypart_id, std::vector< const item * > > &  clothing_map) const

Returns warmth provided by armor, etc.

Definition at line 9379 of file character.cpp.

9381{
9382 std::map<bodypart_id, int> ret;
9383 for( const bodypart_id &bp : get_all_body_parts() ) {
9384 ret.emplace( bp, 0 );
9385 }
9386
9387 for( const std::pair<const bodypart_id, std::vector<const item *>> &on_bp : clothing_map ) {
9388 const bodypart_id &bp = on_bp.first;
9389 for( const item *it : on_bp.second ) {
9390 double warmth = it->get_warmth();
9391 // Warmth reduced linearly with wetness
9392 const auto &materials = it->made_of();
9393 float max_wet_resistance = std::accumulate( materials.begin(), materials.end(), 0.0f,
9394 []( float best, const material_id & mat ) {
9395 return std::max( best, mat->warmth_when_wet() );
9396 } );
9397 float wet_mult = 1.0f - max_wet_resistance * body_wetness[bp->token] / drench_capacity[bp->token];
9398 ret[bp] += warmth * wet_mult;
9399 }
9400 ret[bp] += get_effect_int( effect_heating_bionic, bp->token );
9401 }
9402 return ret;
9403}
static const efftype_id effect_heating_bionic("heating_bionic")
int get_warmth() const
Returns the warmth value that this item has when worn.
Definition: item.cpp:5928

References body_wetness, drench_capacity, effect_heating_bionic, Creature::get_all_body_parts(), Creature::get_effect_int(), item::get_warmth(), item::made_of(), and cata::hash64_detail::ret.

Referenced by weather_effect::wet_player().

◆ wear_item()

std::optional< std::list< item >::iterator > Character::wear_item ( const item to_wear,
bool  interactive = true 
)

Wear a copy of specified item.

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success.

Definition at line 2129 of file character.cpp.

2130{
2131 const auto ret = can_wear( to_wear );
2132 if( !ret.success() ) {
2133 if( interactive ) {
2134 add_msg_if_player( m_info, "%s", ret.c_str() );
2135 }
2136 return std::nullopt;
2137 }
2138
2139 const bool was_deaf = is_deaf();
2140 const bool supertinymouse = get_size() == MS_TINY;
2141 last_item = to_wear.typeId();
2142
2143 std::list<item>::iterator position = position_to_wear_new_item( to_wear );
2144 std::list<item>::iterator new_item_it = worn.insert( position, to_wear );
2145
2146 if( interactive ) {
2148 _( "You put on your %s." ),
2149 _( "<npcname> puts on their %s." ),
2150 to_wear.tname() );
2151 moves -= item_wear_cost( to_wear );
2152
2153 for( const body_part bp : all_body_parts ) {
2154 if( to_wear.covers( bp ) && encumb( bp ) >= 40 ) {
2156 bp == bp_eyes ?
2157 _( "Your %s are very encumbered! %s" ) : _( "Your %s is very encumbered! %s" ),
2158 body_part_name( bp ), encumb_text( bp ) );
2159 }
2160 }
2161 if( !was_deaf && is_deaf() ) {
2162 add_msg_if_player( m_info, _( "You're deafened!" ) );
2163 }
2164 if( supertinymouse && !to_wear.has_flag( flag_UNDERSIZE ) ) {
2166 _( "This %s is too big to wear comfortably! Maybe it could be refitted." ),
2167 to_wear.tname() );
2168 } else if( !supertinymouse && to_wear.has_flag( flag_UNDERSIZE ) ) {
2170 _( "This %s is too small to wear comfortably! Maybe it could be refitted." ),
2171 to_wear.tname() );
2172 }
2173 } else {
2174 add_msg_if_npc( _( "<npcname> puts on their %s." ), to_wear.tname() );
2175 }
2176
2177 new_item_it->on_wear( *this );
2178
2179 inv.update_invlet( *new_item_it );
2180 inv.update_cache_with_item( *new_item_it );
2181
2184
2185 return new_item_it;
2186}
std::string encumb_text(body_part bp)
Returns the matching encumbrance text for a given body_part token.
Definition: bodypart.cpp:360
static const std::string flag_UNDERSIZE("UNDERSIZE")
void update_invlet(item &it, bool assign_invlet=true)
Definition: inventory.cpp:1218
void update_cache_with_item(item &newit)
Definition: inventory.cpp:254

References _, Creature::add_msg_if_npc(), Creature::add_msg_if_player(), Creature::add_msg_player_or_npc(), all_body_parts, body_part_name(), bp_eyes, can_wear(), item::covers(), encumb(), encumb_text(), flag_UNDERSIZE(), get_size(), item::has_flag(), inv, is_deaf(), item_wear_cost(), last_item, m_info, m_warning, Creature::moves, MS_TINY, position, position_to_wear_new_item(), recalc_sight_limits(), reset_encumbrance(), cata::hash64_detail::ret, item::tname(), item::typeId(), inventory::update_cache_with_item(), inventory::update_invlet(), and worn.

Referenced by activity_on_turn_wear(), iexamine::autodoc(), avatar::create(), dispose_item(), pick_one_up(), spell_effect::spawn_ethereal_item(), standard_npc::standard_npc(), npc::stow_item(), avatar_funcs::use_item(), npc::wear_if_wanted(), and wear_possessed().

◆ wear_possessed()

std::optional< std::list< item >::iterator > Character::wear_possessed ( item to_wear,
bool  interactive = true 
)

Wear specified item.

Item must be in characters possession (wielded or stored).

Parameters
to_wearItem to wear
interactiveIf set, won't alert the player or drain moves on completion
Returns
nullopt on fail, pointer to newly worn item on success

Definition at line 2977 of file character.cpp.

2978{
2979 if( is_worn( to_wear ) ) {
2980 if( interactive ) {
2982 _( "You are already wearing that." ),
2983 _( "<npcname> is already wearing that." )
2984 );
2985 }
2986 return std::nullopt;
2987 }
2988 if( to_wear.is_null() ) {
2989 if( interactive ) {
2991 _( "You don't have that item." ),
2992 _( "<npcname> doesn't have that item." ) );
2993 }
2994 return std::nullopt;
2995 }
2996
2997 bool was_weapon;
2998 item to_wear_copy( to_wear );
2999 item &weapon = primary_weapon();
3000 if( &to_wear == &weapon ) {
3001 weapon = item();
3002 was_weapon = true;
3003 } else {
3004 inv.remove_item( &to_wear );
3005 inv.restack( *this->as_player() );
3006 was_weapon = false;
3007 }
3008
3009 auto result = wear_item( to_wear_copy, interactive );
3010 if( !result ) {
3011 if( was_weapon ) {
3012 weapon = to_wear_copy;
3013 } else {
3014 inv.add_item( to_wear_copy, true );
3015 }
3016 return std::nullopt;
3017 }
3018
3019 return result;
3020}

References _, inventory::add_item(), Creature::add_msg_player_or_npc(), Creature::as_player(), inv, item::is_null(), is_worn(), m_info, primary_weapon(), inventory::remove_item(), inventory::restack(), and wear_item().

Referenced by examine_item_menu::run(), show_armor_layers_ui(), and wear().

◆ wearing_something_on()

bool Character::wearing_something_on ( const bodypart_id bp) const

Returns true if the character is wearing something on the entered body part.

Definition at line 8866 of file character.cpp.

8867{
8868 for( auto &i : worn ) {
8869 if( i.covers( bp->token ) ) {
8870 return true;
8871 }
8872 }
8873 return false;
8874}

References worn.

Referenced by armwear_factor(), can_drink_nectar(), can_wear(), iexamine::chainfence(), footwear_factor(), on_hit(), reset_stats(), suffer_from_sunburn(), and suffer_in_sunlight().

◆ weight_capacity()

units::mass Character::weight_capacity ( ) const
overridevirtual
Strength increases carrying capacity

Reimplemented from Creature.

Definition at line 2627 of file character.cpp.

2628{
2630 // Infinite enough
2631 return units::mass_max;
2632 }
2633 // Get base capacity from creature,
2634 // then apply player-only mutation and trait effects.
2636 /** @EFFECT_STR increases carrying capacity */
2637 ret += get_str() * 4_kilogram;
2638 ret *= mutation_value( "weight_capacity_modifier" );
2639
2640 units::mass worn_weight_bonus = 0_gram;
2641 for( const item &it : worn ) {
2642 ret *= it.get_weight_capacity_modifier();
2643 worn_weight_bonus += it.get_weight_capacity_bonus();
2644 }
2645
2646 units::mass bio_weight_bonus = 0_gram;
2647 for( const bionic_id &bid : get_bionics() ) {
2648 ret *= bid->weight_capacity_modifier;
2649 bio_weight_bonus += bid->weight_capacity_bonus;
2650 }
2651
2652 ret += bio_weight_bonus + worn_weight_bonus;
2653
2655 ret += 22500_gram;
2656 }
2657
2658 if( ret < 0_gram ) {
2659 ret = 0_gram;
2660 }
2661 if( is_mounted() ) {
2662 auto *mons = mounted_creature.get();
2663 // the mech has an effective strength for other purposes, like hitting.
2664 // but for lifting, its effective strength is even higher, due to its sturdy construction, leverage,
2665 // and being built entirely for that purpose with hydraulics etc.
2666 ret = mons->mech_str_addition() == 0 ? ret : ( mons->mech_str_addition() + 10 ) * 4_kilogram;
2667 }
2668 return ret;
2669}
virtual units::mass weight_capacity() const
Definition: creature.cpp:1834
@ AEP_CARRY_MORE
Definition: enums.h:118

References AEP_CARRY_MORE, get_bionics(), get_str(), has_artifact_with(), has_trait(), is_mounted(), units::mass_max, mounted_creature, mutation_value(), cata::hash64_detail::ret, trait_DEBUG_STORAGE, Creature::weight_capacity(), and worn.

Referenced by activate_bionic(), are_requirements_nearby(), burn_move_stamina(), can_pick_weight(), carry_weight_string(), pickup::cost_to_move_item(), overmap_ui::display(), pickup::do_pickup(), draw_speed_tab(), draw_stats_info(), draw_weightvolume_labels(), npc::drop_items(), fetch_activity(), find_best_bench(), npc::find_item(), inventory_selector::get_raw_stats(), inventory_drop_selector::get_raw_stats(), iexamine::ledge(), npc_pickup_from_stack(), trading_window::perform_trade(), recalc_speed_bonus(), set_stats(), suffer_while_awake(), and weight_carried_reduced_by().

◆ weight_carried()

◆ weight_carried_reduced_by()

units::mass Character::weight_carried_reduced_by ( const excluded_stacks without) const

Definition at line 2569 of file character.cpp.

2570{
2571 const std::map<const item *, int> empty;
2572
2573 // Worn items
2574 units::mass ret = 0_gram;
2575 for( auto &i : worn ) {
2576 if( !without.count( &i ) ) {
2577 ret += i.weight();
2578 }
2579 }
2580
2581 // Items in inventory
2582 ret += inv.weight_without( without );
2583
2584 // Wielded item
2585 units::mass weaponweight = 0_gram;
2586 const item &weapon = primary_weapon();
2587 auto weapon_it = without.find( &weapon );
2588 if( weapon_it == without.end() ) {
2589 weaponweight = weapon.weight();
2590 } else {
2591 int subtract_count = ( *weapon_it ).second;
2592 if( weapon.count_by_charges() ) {
2593 item copy = weapon;
2594 copy.charges -= subtract_count;
2595 if( copy.charges < 0 ) {
2596 debugmsg( "Trying to remove more charges than the wielded item has" );
2597 copy.charges = 0;
2598 }
2599 weaponweight = copy.weight();
2600 } else if( subtract_count > 1 ) {
2601 debugmsg( "Trying to remove more than one wielded item" );
2602 }
2603 }
2604 // Exclude wielded item if using lifting tool
2605 if( weaponweight + ret > weight_capacity() ) {
2606 const float liftrequirement = std::ceil( units::to_gram<float>( weaponweight ) /
2607 units::to_gram<float>( TOOL_LIFT_FACTOR ) );
2608 if( g->new_game || best_nearby_lifting_assist() < liftrequirement ) {
2609 ret += weaponweight;
2610 }
2611 } else {
2612 ret += weaponweight;
2613 }
2614
2615 return ret;
2616}
units::mass weight_without(const excluded_stacks &without) const
Definition: inventory.cpp:1043
static constexpr units::mass TOOL_LIFT_FACTOR

References best_nearby_lifting_assist(), item::charges, item::count_by_charges(), debugmsg, g, inv, primary_weapon(), cata::hash64_detail::ret, TOOL_LIFT_FACTOR, item::weight(), weight_capacity(), inventory::weight_without(), and worn.

Referenced by inventory_drop_selector::get_raw_stats(), and weight_carried().

◆ wield()

virtual bool Character::wield ( item target)
pure virtual

Removes currently wielded item (if any) and replaces it with the target item.

Parameters
targetreplacement item to wield or null item to remove existing weapon without replacing it
Returns
whether both removal and replacement were successful (they are performed atomically)

Implemented in npc, and avatar.

Referenced by handle_melee_wear(), mount_creature(), perform_technique(), pick_one_up(), and mattack::riotbot().

◆ wielded_items() [1/2]

std::vector< item * > Character::wielded_items ( )

Returns all equipped items that require a limb to be held.

Definition at line 186 of file melee.cpp.

187{
188 if( get_body().find( body_part_arm_r ) == get_body().end() ) {
189 return {};
190 }
191 const bodypart &right_arm = get_part( body_part_arm_r );
192 const auto wielded = right_arm.wielding.wielded;
193 if( wielded != nullptr && !wielded->is_null() ) {
194 return {& *wielded};
195 }
196
197 return {};
198}

References body_part_arm_r, detail::find(), Creature::get_body(), Creature::get_part(), wield_status::wielded, and bodypart::wielding.

Referenced by player::get_eligible_containers_for_crafting(), has_artifact_with(), npc_trading::init_selling(), avatar_action::plthrow(), avatar_action::reload_weapon(), avatar_action::reload_wielded(), and wielded_items().

◆ wielded_items() [2/2]

std::vector< const item * > Character::wielded_items ( ) const

Definition at line 200 of file melee.cpp.

201{
202 const auto nonconst_ret = const_cast<Character *>( this )->wielded_items();
203 return std::vector<const item *>( nonconst_ret.begin(), nonconst_ret.end() );
204}

References wielded_items().

◆ will_eat()

ret_val< edible_rating > Character::will_eat ( const item food,
bool  interactive = false 
) const

Same as can_eat, but takes consequences into account.

Asks about them if

Parameters
interactiveis true, refuses otherwise.

Definition at line 732 of file consumption.cpp.

733{
734 const auto ret = can_eat( food );
735 if( !ret.success() ) {
736 if( interactive ) {
737 add_msg_if_player( m_info, "%s", ret.c_str() );
738 }
739 return ret;
740 }
741
742 std::vector<ret_val<edible_rating>> consequences;
743 const auto add_consequence = [&consequences]( const std::string & msg, edible_rating code ) {
744 consequences.emplace_back( ret_val<edible_rating>::make_failure( code, msg ) );
745 };
746
747 const bool saprophage = has_trait( trait_SAPROPHAGE );
748 const auto &comest = food.get_comestible();
749
750 if( food.rotten() ) {
751 const bool saprovore = has_trait( trait_SAPROVORE );
752 if( !saprophage && !saprovore && !has_bionic( bio_digestion ) ) {
753 add_consequence( _( "This is rotten and smells awful!" ), edible_rating::rotten );
754 }
755 }
756
757 const bool carnivore = has_trait( trait_CARNIVORE );
758 if( food.has_flag( flag_CANNIBALISM ) && !has_trait_flag( "CANNIBAL" ) ) {
759 add_consequence( _( "The thought of eating human flesh makes you feel sick." ),
761 }
762
763 const bool edible = comest->comesttype == comesttype_FOOD || food.has_flag( flag_USE_EAT_VERB );
764
765 int food_kcal = compute_effective_nutrients( food ).kcal;
766 if( food_kcal > 0 && has_effect( effect_nausea ) ) {
767 add_consequence( _( "You still feel nauseous and will probably puke it all up again." ),
769 }
770
771 if( ( food_kcal > 0 || comest->quench > 0 ) && has_effect( effect_bloated )
772 && !food.has_flag( flag_NO_BLOAT ) ) {
773 add_consequence( _( "You're full and will vomit if you try to consume anything." ),
775 }
776
777 if( ( allergy_type( food ) != MORALE_NULL ) || ( carnivore && food.has_flag( flag_ALLERGEN_JUNK ) &&
778 !food.has_flag( flag_CARNIVORE_OK ) ) ) {
779 add_consequence( _( "Your stomach won't be happy (allergy)." ), edible_rating::allergy );
780 }
781
782 if( saprophage && edible && food.rotten() && !food.has_flag( flag_FERTILIZER ) ) {
783 // Note: We're allowing all non-solid "food". This includes drugs
784 // Hard-coding fertilizer for now - should be a separate flag later
785 //~ No, we don't eat "rotten" food. We eat properly aged food, like a normal person.
786 //~ Semantic difference, but greatly facilitates people being proud of their character.
787 add_consequence( _( "Your stomach won't be happy (not rotten enough)." ),
789 }
790
791 if( !food.has_infinite_charges() &&
792 ( ( food_kcal > 0 &&
793 get_stored_kcal() + stomach.get_calories() + food_kcal
794 > max_stored_kcal() ) ||
795 ( comest->quench > 0 && get_thirst() < comest->quench ) ) ) {
796 add_consequence( _( "You're full already and the excess food will be wasted." ),
798 }
799
800 if( !consequences.empty() ) {
801 if( !interactive ) {
802 return consequences.front();
803 }
804 std::string req;
805 for( const auto &elem : consequences ) {
806 req += elem.str() + "\n";
807 }
808
809 const bool eat_verb = food.has_flag( flag_USE_EAT_VERB );
810 std::string food_tname = food.tname();
811 const nc_color food_color = food.color_in_inventory();
812 if( eat_verb || comest->comesttype == comesttype_FOOD ) {
813 req += string_format( _( "Eat your %s anyway?" ), colorize( food_tname, food_color ) );
814 } else if( !eat_verb && comest->comesttype == comesttype_DRINK ) {
815 req += string_format( _( "Drink your %s anyway?" ), colorize( food_tname, food_color ) );
816 } else {
817 req += string_format( _( "Consume your %s anyway?" ), colorize( food_tname, food_color ) );
818 }
819
820 if( !query_yn( req ) ) {
821 return consequences.front();
822 }
823 }
824 // All checks ended, it's edible (or we're pretending it is)
826}
edible_rating
Definition: character.h:164
bool has_infinite_charges() const
Definition: item.cpp:9968
The class represents a composite return value of an arbitrary function (result).
Definition: ret_val.h:21
static const std::string flag_FERTILIZER("FERTILIZER")
static const efftype_id effect_nausea("nausea")

References _, Creature::add_msg_if_player(), allergy, allergy_type(), allergy_weak, bio_digestion, bloated, can_eat(), cannibalism, item::color_in_inventory(), colorize(), comesttype_DRINK(), comesttype_FOOD(), compute_effective_nutrients(), edible, effect_bloated, effect_nausea, flag_ALLERGEN_JUNK(), flag_CANNIBALISM(), flag_CARNIVORE_OK(), flag_FERTILIZER(), flag_NO_BLOAT(), flag_USE_EAT_VERB(), stomach_contents::get_calories(), item::get_comestible(), get_stored_kcal(), get_thirst(), has_bionic(), Creature::has_effect(), item::has_flag(), item::has_infinite_charges(), has_trait(), has_trait_flag(), nutrients::kcal, m_info, ret_val< T >::make_success(), max_stored_kcal(), MORALE_NULL, nausea, query_yn(), cata::hash64_detail::ret, rotten, item::rotten(), stomach, string_format(), item::tname(), too_full, trait_CARNIVORE, trait_SAPROPHAGE, and trait_SAPROVORE.

Referenced by item::color_in_inventory(), npc::consume_food(), eat(), find_auto_consume(), examine_item_menu::rate_action_eat(), and npc::value().

◆ worn_position_to_index()

static int Character::worn_position_to_index ( int  position)
inlinestatic

Definition at line 1092 of file character.h.

1092 {
1093 return -2 - position;
1094 }

References position.

Referenced by advanced_inventory::action_examine(), get_item_position(), i_at(), i_rem(), and avatar_action::wield().

◆ worn_with_flag()

Member Data Documentation

◆ _skills

◆ activity

player_activity Character::activity

Definition at line 1576 of file character.h.

Referenced by activate_mutation(), activity_on_turn_move_loot(), assign_activity(), assign_stashed_activity(), iexamine::autodoc(), activity_handlers::build_do_turn(), iuse::burrow(), game::butcher(), butcher_corpse_activity(), character_effects::calc_focus_equilibrium(), cancel_activity(), game::cancel_activity_or_ignore_query(), game::cancel_activity_query(), check_outbounds_activity(), iuse::chop_logs(), chop_plank_activity(), iuse::chop_tree(), chop_tree_activity(), iuse::clear_rubble(), complete_construction(), veh_interact::complete_vehicle(), construction_activity(), iuse::craft(), iuse::cut_log_into_planks(), veh_interact::do_main_loop(), npc::do_player_activity(), npc::do_pulp(), avatar::do_read(), game::do_turn(), player_activity::do_turn(), pickup_activity_actor::do_turn(), npc::drop(), eff_fun_bleed(), fall_asleep(), fetch_activity(), iuse::fill_pit(), activity_handlers::find_mount_do_turn(), npc::finish_read(), iuse::fishing_rod(), game::forced_door_closing(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), player_activity::get_progress_message(), talk_function::give_aid(), talk_function::give_all_aid(), avatar_funcs::gunmod_add(), iuse::hacksaw(), iuse::hand_crank(), game::handle_key_blocking_activity(), hardcoded_effects(), has_activity(), npc::has_player_activity(), in_sleep_state(), install_bionics(), vehicle::interact_with(), inv_internal(), iuse::jackhammer(), load(), npc::load(), iuse::makemound(), monexamine::milk_source(), mine_activity(), npc::move(), map::move_vehicle(), npc::on_load(), iuse::oxytorch(), perform_zone_activity_turn(), iuse::pickaxe(), game::place_player(), monexamine::play_with(), iuse::portable_game(), game::process_activity(), sounds::process_sound_markers(), process_turn(), game::process_voluntary_act_interrupt(), avatar::read(), npc::reboot(), avatar_action::reload(), DefaultRemovePartHandler::removed(), activity_handlers::repair_item_finish(), resume_backlog_activity(), npc::revert_after_activity(), iexamine::rubble(), iexamine::safe(), conditional_t< T >::set_has_activity(), npc::set_mission(), monexamine::shear_animal(), show_armor_layers_ui(), iexamine::shrub_wildveggies(), smash(), player::start_craft(), store(), npc::talk_to_u(), avatar_funcs::toolmod_add(), iexamine::trap(), try_start_hacking(), uninstall_bionic(), update_needs(), pick_lock_actor::use(), firestarter_actor::use(), enzlave_actor::use(), ammobelt_actor::use(), repair_item_actor::use(), heal_actor::use(), cast_spell_actor::use(), heal_actor::use_healing_item(), vehicle_activity(), and iuse::vibe().

◆ activity_vehicle_part_index

◆ addictions

◆ ammo_location

item_location Character::ammo_location

Definition at line 1600 of file character.h.

◆ anchor

safe_reference_anchor Character::anchor
private

Definition at line 2277 of file character.h.

Referenced by get_safe_reference().

◆ auto_move_route

std::vector<tripoint> Character::auto_move_route
private

◆ autolearn_skills_stamp

pimpl<SkillLevelMap> Character::autolearn_skills_stamp
mutableprotected

Stamp of character skills.

learned_recipes are valid only with this set of skills.

Definition at line 2173 of file character.h.

Referenced by get_learned_recipes(), load(), and store().

◆ backlog

◆ bio_soporific_powered_at_last_sleep_check

bool Character::bio_soporific_powered_at_last_sleep_check = false

Definition at line 2155 of file character.h.

Referenced by character_funcs::roll_can_sleep(), and avatar_funcs::try_to_sleep().

◆ blocks_left

int Character::blocks_left = 0

Definition at line 568 of file character.h.

Referenced by block_hit(), player::player(), and process_turn().

◆ body_wetness

◆ cached_crafting_inventory

inventory Character::cached_crafting_inventory
private

Definition at line 2273 of file character.h.

Referenced by crafting_inventory().

◆ cached_moves

int Character::cached_moves = 0
private

Definition at line 2271 of file character.h.

Referenced by crafting_inventory().

◆ cached_mutations

std::vector<const mutation_branch *> Character::cached_mutations
protected

◆ cached_position

tripoint Character::cached_position
private

Definition at line 2272 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ cached_time

time_point Character::cached_time

Definition at line 1603 of file character.h.

Referenced by crafting_inventory(), and invalidate_crafting_inventory().

◆ camps

std::set<tripoint_abs_omt> Character::camps

◆ cash

int Character::cash = 0

◆ check_encumbrance

bool Character::check_encumbrance = true
private

◆ consumption_history

pimpl<consumption_history_t> Character::consumption_history

Definition at line 1589 of file character.h.

Referenced by eat(), fun_for(), load(), and store().

◆ controlling_vehicle

◆ custom_profession

std::string Character::custom_profession

◆ damage_bandaged

std::array<int, num_hp_parts> Character::damage_bandaged

Definition at line 1568 of file character.h.

Referenced by heal_actor::finish_using(), load(), regen(), and player::store().

◆ damage_disinfected

std::array<int, num_hp_parts> Character::damage_disinfected

Definition at line 1568 of file character.h.

Referenced by iexamine::autodoc(), heal_actor::finish_using(), load(), regen(), and player::store().

◆ death_drops

bool Character::death_drops = true

Definition at line 252 of file character.h.

Referenced by npc::npc(), place_corpse(), and player::player().

◆ destination_activity

player_activity Character::destination_activity
private

◆ destination_point

◆ dex_bonus

int Character::dex_bonus = 0
protected

◆ dex_cur

◆ dex_max

◆ dodges_left

int Character::dodges_left = 0

Definition at line 569 of file character.h.

Referenced by get_dodge(), game::is_game_over(), on_dodge(), player::player(), and process_turn().

◆ drench_capacity

std::array<int, num_bp> Character::drench_capacity

◆ enchantment_cache

◆ encumbrance_cache

pimpl<char_encumbrance_data> Character::encumbrance_cache
protected

Definition at line 2145 of file character.h.

Referenced by encumb(), extraEncumbrance(), get_encumbrance(), and reset_encumbrance().

◆ fac_id

◆ faction_api_version

int Character::faction_api_version = 2
protected

◆ fatigue

int Character::fatigue = 0
private

◆ fleshy

const std::vector< material_id > Character::fleshy = { material_id( "flesh" ), material_id( "hflesh" ) }
static

Definition at line 784 of file character.h.

Referenced by made_of(), and made_of_any().

◆ focus_pool

◆ follower_ids

std::set<character_id> Character::follower_ids

Definition at line 1598 of file character.h.

◆ frostbite_timer

std::array<int, num_bp> Character::frostbite_timer

Definition at line 2289 of file character.h.

Referenced by load(), store(), and update_bodytemp().

◆ hauling

bool Character::hauling = false

Definition at line 1572 of file character.h.

Referenced by is_hauling(), player::player(), start_hauling(), and stop_hauling().

◆ healed_total

std::array<int, num_hp_parts> Character::healed_total

Definition at line 1777 of file character.h.

Referenced by healed_bp(), load(), and store().

◆ healthy

int Character::healthy = 0
protected

How healthy the character is.

Definition at line 2134 of file character.h.

Referenced by get_healthy(), load(), mod_healthy(), set_healthy(), and store().

◆ healthy_mod

int Character::healthy_mod = 0
protected

Definition at line 2135 of file character.h.

Referenced by get_healthy_mod(), load(), mod_healthy_mod(), set_healthy_mod(), and store().

◆ id

◆ in_vehicle

◆ init_age

int Character::init_age = 25
protected

age in years at character creation

Definition at line 2138 of file character.h.

Referenced by age(), base_age(), load(), mod_base_age(), avatar::randomize(), reset_chargen_attributes(), set_base_age(), and store().

◆ init_height

int Character::init_height = 175
protected

height at character creation

Definition at line 2140 of file character.h.

Referenced by base_height(), height(), load(), mod_base_height(), avatar::randomize(), reset_chargen_attributes(), set_base_height(), and store().

◆ int_bonus

int Character::int_bonus = 0
protected

◆ int_cur

◆ int_max

◆ inv

inventory Character::inv

Definition at line 1579 of file character.h.

Referenced by inventory_selector::add_character_items(), advanced_inventory_pane::add_items_from_area(), allocated_invlets(), npc::alt_attack(), autoclave_internal(), autodoc_internal(), behavior::character_oracle_t::can_make_fire(), can_pick_volume(), player::can_start_craft(), iuse_transform::can_use(), behavior::character_oracle_t::can_wear_warmer_clothes(), debug_menu::character_edit_menu(), game_menus::inv::common(), game_menus::inv::compare(), complete_craft(), consume(), npc::consume_cbm_items(), npc::consume_food(), convert_to_items(), crafting_inventory(), avatar::create(), npc::decide_needs(), die(), dispose_item(), npc::dispose_item(), drop_invalid_inventory(), npc::drop_items(), findBestGasDiscount(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_item_position(), item::get_remaining_capacity_for_liquid(), get_weight(), behavior::character_oracle_t::has_food(), npc::has_painkiller(), behavior::character_oracle_t::has_water(), npc::heal_self(), i_add(), i_add_or_drop(), i_at(), i_rem(), tutorial_game::init(), npc_trading::init_buying(), npc_trading::init_selling(), inv_dump(), inv_internal(), irradiate(), leak_level(), avatar::load(), load(), npc::mug_player(), game_menus::inv::multidrop(), iexamine::pay_gas(), pour_into(), process_items(), iuse::radiocar(), npc::randomize(), game_menus::inv::reassign_letter(), item::reload(), pickup::reorder_for_dropping(), player::select_requirements(), set_item_inventory(), npc::shop_restock(), show_armor_layers_ui(), iuse::smoking(), starting_inv(), avatar::store(), player::store(), game_menus::inv::swap_letters(), avatar_action::swim(), takeoff(), character_funcs::try_wield_contents(), unwield(), npc::update_worst_item_value(), use_amount(), npc::use_painkiller(), volume_carried(), volume_carried_reduced_by(), wash_items(), wear_item(), wear_possessed(), weight_carried_reduced_by(), avatar::wield(), and memorial_logger::write().

◆ known_traps

trap_map Character::known_traps
protected

Definition at line 2144 of file character.h.

Referenced by add_known_trap(), knows_trap(), load(), and store().

◆ last_climate_control_ret

bool Character::last_climate_control_ret = false

Definition at line 2294 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ last_item

◆ last_sleep_check

time_point Character::last_sleep_check = calendar::turn_zero

Definition at line 2154 of file character.h.

Referenced by player::load(), character_funcs::roll_can_sleep(), and player::store().

◆ learned_recipes

pimpl<recipe_subset> Character::learned_recipes
mutableprotected

Subset of learned recipes.

Needs to be mutable for lazy initialization.

Definition at line 2175 of file character.h.

Referenced by avatar::create(), get_learned_recipes(), learn_recipe(), load(), and store().

◆ magic

◆ male

◆ martial_arts_data

◆ max_power_level

◆ melee_miss_reasons

struct weighted_int_list< std::string > Character::melee_miss_reasons
private

Definition at line 2269 of file character.h.

Referenced by add_miss_reason(), clear_miss_reasons(), and get_miss_reason().

◆ morale

◆ mounted_creature

◆ mounted_creature_id

int Character::mounted_creature_id = 0

Definition at line 1617 of file character.h.

Referenced by load().

◆ move_mode

◆ mut_drench

std::array<std::array<int, NUM_WATER_TOLERANCE>, num_bp> Character::mut_drench
protected

Definition at line 858 of file character.h.

Referenced by apply_wetness_morale(), and drench_mut_calc().

◆ mutation_category_level

std::map<std::string, int> Character::mutation_category_level

◆ my_bionics

◆ my_fac

◆ my_mutations

mutation_collection Character::my_mutations

Traits / mutations of the character.

Key is the mutation id (it's also a valid key into mutation_data), the value describes the status of the mutation. If there is not entry for a mutation, the character does not have it. If the map contains the entry, the character has the mutation.

Definition at line 2153 of file character.h.

Referenced by activate_mutation(), active_light(), clear_mutations(), avatar::create(), deactivate_mutation(), get_mutations(), get_overlay_ids(), has_active_mutation(), has_opposite_trait(), has_trait(), load(), mutation_effect(), mutation_spend_resources(), rebuild_mutation_cache(), set_mutation(), detail::show_mutations_ui_internal(), store(), suffer(), switch_mutations(), toggle_trait(), and unset_mutation().

◆ my_traits

std::unordered_set<trait_id> Character::my_traits
protected

Contains mutation ids of the base traits.

Definition at line 2160 of file character.h.

Referenced by clear_mutations(), get_base_traits(), has_base_trait(), load(), store(), and toggle_trait().

◆ name

std::string Character::name

Definition at line 1564 of file character.h.

Referenced by assign_activity(), vehicle::automatic_fire_turret(), bionics_install_failure(), map::board_vehicle(), body_window(), butcher_corpse_activity(), butchery_drops_harvest(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), talk_function::buy_haircut(), talk_function::buy_shave(), veh_interact::calc_overview(), can_wear(), enchantment::cast_enchantment_spell(), debug_menu::character_edit_menu(), avatar::character_to_template(), activity_handlers::chop_logs_finish(), game::cleanup_at_end(), veh_interact::complete_vehicle(), target_ui::confirm_non_enemy_target(), npc::consume_food(), consume_item(), avatar::create(), mission_end::deposit_box(), item_location::impl::item_on_person::describe(), diary::diary(), npc::die(), disp_name(), npc::do_reload(), overmap_ui::draw_ascii(), draw_tip(), npc::drop_items(), dialogue::dynamic_line(), talk_function::end_conversation(), enumerate_unmet_requirements(), npc::execute_action(), extended_description(), npc::faction_display(), fetch_activity(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_plant(), basecamp::finish_return(), ranged::fire_gun(), overmapbuffer::fix_npcs(), talk_function::flee(), talk_function::forage_return(), game::forced_door_closing(), npc::form_opinion(), iuse::geiger(), generic_multi_activity_locations(), get_name(), avatar::get_save_id(), vehicle::get_targeting_npc(), talk_function::give_aid(), talk_function::give_all_aid(), talk_function::give_equipment(), npc::go_to_omt_destination(), npc::handle_sound(), hardcoded_effects(), iexamine::harvest_plant(), healing_rate(), talk_function::hostile(), tutorial_game::init(), talk_function::insult_combat(), activity_handlers::jackhammer_finish(), talk_function::labor_return(), talk_function::leave(), load(), npc_template::load(), game::load(), npc::load_npc_template(), make_fake_npc(), melee_attack(), talk_function::morale_chat_activity(), npc::move(), move_item(), npc::move_to(), npc::mug_player(), mutation_attacks(), game::npc_menu(), npc_temp_orders_menu(), npc_throw(), on_hit(), npc::on_load(), dialogue::opt(), perform_technique(), trading_window::perform_trade(), petfood(), pick_name(), npc::pick_up_item(), activity_handlers::pickaxe_finish(), place_corpse(), mission_start::place_dog(), mission_start::place_npc_software(), npc::print_info(), print_info(), avatar::randomize(), talk_function::remove_overseer(), reveal_target(), rod_fish(), game::save(), avatar::save_template(), npc::say(), npc::scan_new_items(), talk_function::scavenging_patrol_return(), talk_function::scavenging_raid_return(), npc::set_attitude(), set_description(), talk_function::set_npc_pickup(), talk_effect_fun_t::set_u_buy_item(), talk_effect_fun_t::set_u_buy_monster(), talk_effect_fun_t::set_u_sell_item(), npc::setpos(), short_description_parts(), show_armor_layers_ui(), show_photo_selection(), map::smash_trap(), standard_npc::standard_npc(), talk_function::start_mugging(), game_menus::inv::steal(), talk_function::stop_following(), talk_function::stop_guard(), store(), talk_function::stranger_neutral(), suffer_from_schizophrenia(), survive_random_encounter(), npc::talk_to_u(), tidy_activity(), npc::travel_overmap(), avatar_funcs::try_disarm_npc(), avatar_funcs::try_steal_from_npc(), update_time_fixed(), trading_window::update_win(), npc::warn_about(), main_menu::world_tab(), and memorial_logger::write().

◆ next_climate_control_check

time_point Character::next_climate_control_check

Definition at line 2293 of file character.h.

Referenced by in_climate_control(), and game::start_game().

◆ next_expected_position

std::optional<tripoint> Character::next_expected_position
private

◆ npc_ai_info_cache

std::array<double, npc_ai_info::num_npc_ai_info> Character::npc_ai_info_cache
mutableprivate

◆ nv_cached

bool Character::nv_cached = false

Definition at line 1569 of file character.h.

Referenced by action_taken(), has_nv(), player::player(), and reset_stats().

◆ nv_range

float Character::nv_range = 0
protected

Definition at line 2180 of file character.h.

Referenced by get_vision_threshold(), and recalc_sight_limits().

◆ omt_path

◆ overmap_time

std::unordered_map<point_abs_omt, time_duration> Character::overmap_time
protected

Amount of time the player has spent in each overmap tile.

Definition at line 2285 of file character.h.

Referenced by apply_persistent_morale(), load(), process_turn(), and store().

◆ oxygen

◆ path_settings

pimpl<pathfinding_settings> Character::path_settings
mutableprotected

Cache for pathfinding settings.

Most of it isn't changed too often, hence mutable.

Definition at line 2191 of file character.h.

Referenced by get_pathfinding_settings(), npc::get_pathfinding_settings(), avatar::grab(), and npc::npc().

◆ per_bonus

int Character::per_bonus = 0
protected

◆ per_cur

◆ per_max

◆ pkill

int Character::pkill = 0
private

◆ position

◆ power_level

units::energy Character::power_level
private

◆ prof

◆ radiation

int Character::radiation = 0
private

Definition at line 2262 of file character.h.

Referenced by get_rad(), load(), set_rad(), and store().

◆ reach_attacking

bool Character::reach_attacking = false

Definition at line 621 of file character.h.

Referenced by melee_attack(), and reach_attack().

◆ reactor_plut

int Character::reactor_plut = 0

Definition at line 1593 of file character.h.

Referenced by player::load(), and player::store().

◆ recoil

◆ scent

int Character::scent = 0

Definition at line 1584 of file character.h.

Referenced by process_turn().

◆ sight_max

int Character::sight_max = 0
protected

Definition at line 2181 of file character.h.

Referenced by player::player(), recalc_sight_limits(), sight_range(), and unimpaired_range().

◆ size_class

m_size Character::size_class = MS_MEDIUM
protected

Size class of character.

Definition at line 2142 of file character.h.

Referenced by get_size(), and recalculate_size().

◆ sleep_deprivation

int Character::sleep_deprivation = 0
private

◆ slow_rad

int Character::slow_rad = 0

Definition at line 1594 of file character.h.

Referenced by player::load(), and player::store().

◆ stamina

int Character::stamina = 0
private

Definition at line 2253 of file character.h.

Referenced by get_stamina(), load(), mod_stamina(), set_stamina(), and store().

◆ stashed_outbounds_activity

◆ stashed_outbounds_backlog

player_activity Character::stashed_outbounds_backlog

◆ stim

int Character::stim = 0
private

Definition at line 2259 of file character.h.

Referenced by get_stim(), load(), mod_stim(), set_stim(), and store().

◆ stomach

◆ stored_calories

int Character::stored_calories = 0
private

Needs (hunger, starvation, thirst, fatigue, etc.)

Definition at line 2250 of file character.h.

Referenced by get_hunger_description(), get_stored_kcal(), load(), mod_stored_kcal(), set_stored_kcal(), and store().

◆ str_bonus

int Character::str_bonus = 0
protected

Bonuses to stats, calculated each turn.

Definition at line 2128 of file character.h.

Referenced by get_str(), get_str_bonus(), load(), mod_str_bonus(), reset_bonuses(), set_str_bonus(), and store().

◆ str_cur

◆ str_max

◆ tank_plut

int Character::tank_plut = 0

Definition at line 1592 of file character.h.

Referenced by player::load(), and player::store().

◆ temp_conv

◆ temp_cur

◆ thirst

int Character::thirst = 0
private

Definition at line 2252 of file character.h.

Referenced by get_thirst(), get_thirst_description(), load(), mod_thirst(), set_thirst(), and store().

◆ time_died

time_point Character::time_died = calendar::before_time_starts
protected

Definition at line 2185 of file character.h.

Referenced by get_time_died(), and set_time_died().

◆ type_of_scent

scenttype_id Character::type_of_scent
private

Definition at line 2267 of file character.h.

Referenced by get_type_of_scent(), load(), set_type_of_scent(), and store().

◆ vision_mode_cache

std::bitset<NUM_VISION_MODES> Character::vision_mode_cache
protected

◆ vitamin_levels

std::map<vitamin_id, int> Character::vitamin_levels
protected

Current deficiency/excess quantity for each vitamin.

Definition at line 2204 of file character.h.

Referenced by load(), player::player(), store(), vitamin_get(), vitamin_mod(), and vitamin_set().

◆ worn

std::list<item> Character::worn

Definition at line 1567 of file character.h.

Referenced by absorb_hit(), active_light(), advanced_inventory_pane::add_items_from_area(), npc::adjust_worn(), allocated_invlets(), amount_worn(), best_shield(), bodypart_exposure(), can_swap(), can_takeoff(), can_wear(), debug_menu::character_edit_menu(), check_and_recover_morale(), check_art_charge_req(), check_item_encumbrance_flag(), relic_funcs::check_recharge_reqs(), consume(), covered_with_flag(), crafting_inventory(), deal_damage(), dispose_item(), npc::dispose_item(), exclusive_flag_coverage(), extended_description(), fire(), get_armor(), get_armor_bash_base(), get_armor_bullet_base(), get_armor_cut_base(), get_armor_type(), get_dependent_worn_items(), get_effective_efficiency(), player::get_eligible_containers_for_crafting(), item::get_encumber(), get_env_resist(), get_item_position(), get_overlay_ids(), get_weight(), hardcoded_effects(), has_artifact_with(), head_cloth_encumbrance(), i_at(), i_rem(), in_climate_control(), inv_dump(), character_funcs::is_bp_immune_to(), is_wearing(), is_wearing_active_optcloak(), is_wearing_active_power_armor(), is_wearing_helmet(), is_wearing_on_bp(), is_wearing_power_armor(), is_wearing_shoes(), is_worn(), item_encumb(), item_worn_with_flag(), load(), natural_attack_restricted_on(), item::on_wear(), map::player_in_field(), position_to_wear_new_item(), npc::print_info(), process_items(), item::process_tool(), remove_worn_items_with(), short_description_parts(), show_armor_layers_ui(), standard_npc::standard_npc(), starting_clothes(), player::store(), npc::stow_item(), swim_speed(), takeoff(), update_bodytemp(), set_transform_iuse::use(), use_amount(), volume_capacity_reduced_by(), npc::wear_if_wanted(), wear_item(), wearing_something_on(), weight_capacity(), weight_carried_reduced_by(), weather_effect::wet_player(), avatar::wield(), avatar_action::wield(), worn_with_flag(), and memorial_logger::write().


The documentation for this class was generated from the following files: